Android Workshop for NTU. A getting started guide to android application development.
UPDATE (Oct 2013): An updated slide at http://samwize.com/2013/10/13/android-workshop-2013/
22. A couple of steps
• Install SDK
• Setup Emulator
• Run Emulator
• Create Project
• Run Project
23. Install SDKs
1. Install Eclipse - the IDE
http://www.eclipse.org/downloads/packages/eclipse-classic-371/indigosr1
2. Install Android SDK
http://developer.android.com/sdk/index.html
3. Install Android ADT Plugin for Eclipse
http://developer.android.com/sdk/eclipse-adt.html#installing
Guide from http://developer.android.com/sdk/installing.html
24. Setup Emulator
• Add an AVD (Android Virtual Device)
• Go to Windows > AVD Manager > Virtual
devices > New
• Select Google APIs - API Level 10
as target (which is v2.3.3)
28. Create Project
• File > New > Android Project
• Fill in:
• Project name
• Build target
• Application name
• Package name
• Activity
• Min SDK Version
32. Run on Actual Device
• To run on actual Android device, connect
device to computer via USB
• From device, go to Settings > Applications
> Development > enabled USB debugging
• Run project
43. Activity
• Launch an Activity by calling
startActivity(intent)
Launch a known Activity
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
44. Activity
• Launch an Activity by calling
startActivity(intent)
Launch a known Activity
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
Launch a system Activity
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
45. Activity
• Activity must be declared in AndroidManifest.xml
<manifest ... >
<application ... >
<activity android:name=".HelloWorldActivity" />
...
</application ... >
...
</manifest >
46. Service
• Service runs in the background, even when user is not
interacting with your app
• Service or Thread ?
• To start, call startService()
• Similar to Activity, has its lifecycle and various event
callbacks
47. ContentProvider
• A way to share data across applications,
including apps such as phonebook,
calendar, etc.
• In other words, you can access the
phonebook using a ContentProvider
• Have query, insert, delete methods (SQLite)
ContentResolver cr = getContentResolver();
cr.query(“content://android.provider.Contacts.Phones.CONTACT_URI”,
projection,
selection, selectionArg,
sortOrder)
48. BroadcastReceiver
• Responds to system-wide broadcast
announcements such as incoming phone
call, SMS sent, picture captured, etc
57. The way of XML
/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
58. The way of XML
/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
looks in /res/values/string.xml, and
find the value for the key “hello”
59. The way of XML
/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
Equivalently..
android:text="Hello world too!"
60. The way of XML
/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
61. The way of XML
/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
setContentView() inflate main.xml and set the views
62. The way of Code
package com.just2us.helloandroid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("Hello, Android");
setContentView(textview);
}
}
63. The way of Code
package com.just2us.helloandroid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("Hello, Android");
setContentView(textview);
}
}
Creating a TextView and set the text
64. The way of Code
package com.just2us.helloandroid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("Hello, Android");
setContentView(textview);
}
}
Similarly to the way of XML, setContentView()
65. The way of Code
package com.just2us.helloandroid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("Hello, Android");
setContentView(textview);
}
}
71. Preferences
• The easiest way to store information
• NOT only store preferences/settings, but
also arbitrary key-value pairs
• SharedPreference class
• getBoolean, setBoolean, etc..
72. Preferences
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
@Override
protected void onCreate(Bundle state){
super.onCreate(state);
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
@Override
protected void onStop(){
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// Commit the edits!
editor.commit();
}
}
74. Database
public class DictionaryOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DICTIONARY_TABLE_NAME = "dictionary";
private static final String DICTIONARY_TABLE_CREATE =
"CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
KEY_WORD + " TEXT, " +
KEY_DEFINITION + " TEXT);";
DictionaryOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DICTIONARY_TABLE_CREATE);
}
}
75. Database
• Call getWritableDatabase() or
getReadableDatabase() to get an
SQLiteDatabase object
• With SQLiteDatabase, call query() to
execute SQL queries
76. Network
• Connect to web services over HTTP
• Permission needed in Manifest
<uses-permission android:name="android.permission.INTERNET" />
• A few different ways to connect
• HttpClient is most robust
77. Network - GET
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://www.myserver.com/script1.php");
// Execute HTTP GET request and get response
HttpResponse response = client.execute(request);
InputStream is = response.getEntity().getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
// Do what you need with content StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String content = sb.toString();
// Do what you need with content
...
78. Network - POST
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost("http://www.myserver.com/login_script.php");
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", "samwize"));
nameValuePairs.add(new BasicNameValuePair("password", "123456"));
request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP POST Request
HttpResponse response = httpclient.execute(request);
81. Multimedia - Camera
• 2 ways to capture photo
• Using capture intent
• Using Camera class directly
82. Multimedia - Camera
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private Uri fileUri;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
Capture photo
83. Multimedia - Camera
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
private Uri fileUri;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}
84. Multimedia - Camera
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
private Uri fileUri;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}
Capture video
85. Multimedia - Camera
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:n" +
data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Video saved to:n" +
data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the video capture
} else {
// Video capture failed, advise user
}
}
}
Handling after photo/video is captured by camera app
86. Multimedia - MediaPlayer
• Play audio and video from:
• /res/raw/
• File system (internal or external)
• Stream over Internet
• MediaPlayer class
89. Multimedia - MediaPlayer
String url = "http://........"; // your streaming URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();
Playing audio stream from Internet
90. Multimedia - MediaPlayer
• Playing video is similar to audio
• Pass a SurfaceHolder (view class) which the
MediaPlayer can render the video on
94. Notepad Tutorial
• Exercise 1- ListActivity and database
http://developer.android.com/resources/tutorials/notepad/notepad-ex1.html
• Exercise 2 - Invoke another activity
• Exercise 3 - application life cycle
95. Sample Code
• Sample Codes
http://developer.android.com/resources/samples/get.html
• API Demo, Bluetooth Chat, News Reader,
Accelerometer Play, Contact Manager, etc
96. User Interfaces
• Supporting different screen sizes
http://developer.android.com/guide/practices/screens_support.html
• Common UI Patterns
http://www.androidpatterns.com/
4-hour Android workshop\nGet started\nZero Android, but some programming knowledge\n\nFor NTU School of EEE, Design & Innovation Project (DIP)\n12 teams (of 10 members)\nhttp://www.eee.ntu.edu.sg/events/Design%20and%20Innovation%20Project/Pages/Introduction.aspx\n
Get to know me, my experience\nFor you to ask relevant questions\nEven as a consultant to your projects\nDOWNLOAD the slides\n
write lots mobile apps\nStarted with WAP > Java ME > BB > iPhone > Android > WP7\nSkipped Symbian.. \nMy hobby apps, now..\n
write lots mobile apps\nStarted with WAP > Java ME > BB > iPhone > Android > WP7\nSkipped Symbian.. \nMy hobby apps, now..\n
write lots mobile apps\nStarted with WAP > Java ME > BB > iPhone > Android > WP7\nSkipped Symbian.. \nMy hobby apps, now..\n
Some of my Android apps\nSecret to do this that\nSMS template app\n
\n
\n
\n
\n
\n
Android as an OS\nHands On Coding, and break if done\nGuidance to life after this 4hr\n
Fun Company\nGreen robot\nFav desserts\nhttp://developer.android.com/guide/basics/what-is-android.html\nhttp://kschang.hubpages.com/slide/Cupcake-Donut-Eclair-Froyo-Gingerbread-Honeycomb-Android-OS-Version-Codenames-and-Why/4609964\n
Android is everywhere - Phones, tablets, Google TV. Future: Cars, tanks.\nPhone - most prevalent. A device with lots of I/O. Also small.\n\n
Android != Linux\nUsed Linux security, mem mgmt, threading, etc\nEach app, 1 VM instance\nOptimized for mobile\nAndroid Package. A zip. Like Jar.\nApplication Framework = APIs - Storage, Network, Multimedia, GPS, Phone services (see next)\n
An open development platform.\n4 Abstraction layers\nAndroid offers developers the ability to build extremely rich and innovative applications - take advantage of the device hardware, etc\nDevelopers have full access to the same framework APIs used by the core applications. \nThe application architecture is designed to simplify the reuse of components. allows components to be replaced by the user.\nhttp://developer.android.com/guide/basics/what-is-android.html\n
All files under res are parsed and accessible in code by eg. R.layout.main and R.drawable.icon\n
All files under res are parsed and accessible in code by eg. R.layout.main and R.drawable.icon\n
All files under res are parsed and accessible in code by eg. R.layout.main and R.drawable.icon\n
All files under res are parsed and accessible in code by eg. R.layout.main and R.drawable.icon\n
All files under res are parsed and accessible in code by eg. R.layout.main and R.drawable.icon\n
All files under res are parsed and accessible in code by eg. R.layout.main and R.drawable.icon\n
All files under res are parsed and accessible in code by eg. R.layout.main and R.drawable.icon\n
Foundation for an app is contained in this xml - the activities, services, intents, and so on. \nWhich activity appear on device&#x2019;s launcher\nApp name, icon, etc\n
Activity - A single screen (UI)\nService - background activity eg. play music globally\nContentProvider - Even share data across apps. SQLite. eg. contacts. ContentResolver\nBroadcastReceiver - Responds to system wide broadcast announcements. Usually from the system eg. Send Message, Picture captured\n\nhttp://developer.android.com/guide/topics/fundamentals.html\n
It is a screen/window to draw your UI.\nAn app makes up of 1 or more activities\nScreens stack up. When BACK is pressed, the top screen is removed, and the one below is shown. \nFIFO\nhttp://developer.android.com/guide/topics/fundamentals/activities.html\n
Activity lifecycle\nPause - a call comes in, a notification is shown over the screen\nStop - screen is no longer visible\n
\n
\n
In an Activity class, call startActivity with an Intent.\nConcept of intent\nA few different ways to construct the intent.\n
\n
Thread, does NOT run when app is in background\nhttp://developer.android.com/guide/topics/fundamentals/services.html\n\n