mobile programming lecture 8

143
Mobile Programming Lecture 8 Notifications, Services, AsyncTask

Upload: talasi

Post on 24-Feb-2016

47 views

Category:

Documents


0 download

DESCRIPTION

Mobile Programming Lecture 8. Notifications, Services, AsyncTask. Lecture 7 Review. How and where in your code do you distinguish between multiple Dialogs in an Activity? How and where in your code do you determine which Menu Option was clicked? - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Mobile Programming Lecture 8

Mobile Programming Lecture 8

Notifications, Services, AsyncTask

Page 2: Mobile Programming Lecture 8

• How and where in your code do you distinguish

between multiple Dialogs in an Activity?

• How and where in your code do you determine

which Menu Option was clicked?

• After creating an Options Menu, can you use

the same XML file to create a Context Menu?

Lecture 7 Review

Page 3: Mobile Programming Lecture 8

• How can you edit SharedPreferences?

• What's the difference between calling

o getSharedPreferences(String, int) and

o getDefaultSharedPreferences(Context);

• How can you tell when Preferences have been changed

at runtime?

Lecture 7 Review

Page 4: Mobile Programming Lecture 8

Agenda

• NotificationManager

• Notification

• PendingIntent

• Service

• Communicating with Service

• MediaPlayer

• AsyncTask

Page 5: Mobile Programming Lecture 8

Notifications

• Notifications give you the ability to let the user know directly about what work has been completed

• �Send a notification that the file has started downloading

• After the file completes the service can send out a notification saying that the file has been downloaded successfully.

Page 6: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

Page 7: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

Although Notifications are usually sent from Services, we send it from an Activity since that's what you know at this point

Page 8: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

This will be used as an identifier for this notification unique within this application.

Page 9: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

You must use the NotificationManager if you want to send a Notification

Page 10: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher, "Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

Let's create a new Notification

Page 11: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

First argument is an icon which should be in res/drawable. I reused the launcher icon here because I'm lazy

Page 12: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

This is the message that pops up in the status bar when the Notification is delivered. The user doesn't see this message again after that

Page 13: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

This is the time that will be shown in the Notification, not the time that the Notification will be delivered.

Page 14: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

Let's set up an Intent for launching a new Activity

Page 15: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

Since we don't control the NotificationManager, we need to supply it with our Intent so that it can act on our behalf

Page 16: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

In this case, we want it to launch our second Activity, so we provide it with an Intent that does just that

Page 17: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

Let's add information for our Notification

Page 18: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

We need the Context of our application

Page 19: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

A Title that the user will see in the Notification until it dissappears

Page 20: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

A message that appears below the Title

Page 21: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

Our PendingIntent to be launched when the Notification is clicked

Page 22: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR; mNotificationManager.notify(NOTIFICATION_ID, notification);

}

You can add flags to your Notification. Use | to add multiple flags

Page 23: Mobile Programming Lecture 8

Notificationspublic class NotificationExample extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final int NOTIFICATION_ID = 1;

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.ic_launcher,

"Hi There", System.currentTimeMillis());

Intent notificationIntent = new Intent(this, SecondActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, "You have been notified",

"Click to launch second Activity", contentIntent);

notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(NOTIFICATION_ID, notification);

}

Notify the user! You need to supply an id (int) unique within this application, and the Notification itself

Page 24: Mobile Programming Lecture 8

Notifications

• See NotificationExample.tar

• Note that this way of doing it is deprecated

• Android 3.0 and higher can still use it, but should use Notification.Builder instead• http://developer.android.com/training/notify-user/build

-notification.html

Page 25: Mobile Programming Lecture 8

Android Application Components

1. Activity

2. Broadcast Receiver

3. Content Provider

4. Service

Page 26: Mobile Programming Lecture 8

Service - What is it?

• a Service is an application component representing an application's desire to o perform a longer-running operation while not

interacting with the usero supply functionality for other applications to use

• a Service is a facility for the application too tell the system about something it wants to be doing

in the background o expose some of its functionality to other applications

Page 27: Mobile Programming Lecture 8

Service - What is it NOT?

• �a Service is not a separate process.o it does not imply it is running in its own process o it runs in the same process as the application it is in

unless otherwise specified

• �a Service is not a thread

• it is not a means itself to do work off the main thread

Page 28: Mobile Programming Lecture 8

Service - Why use Services?• �For functions that do not require access to an activity’s UI

o Performing operations that need to continue even after the application’s activities are not visible �Long Downloads (Android Market) �Playing Music (Pandora)

• �Performing operations that need to exist regardless of activities coming and goingo �Maintaining a connection for a chat application

• �Performing periodic work without user intervention.o �Updating the Weather Widget.

Page 29: Mobile Programming Lecture 8

Service - Process LifeCycle

Android will attempt to keep the process hosting a service around as long as the service has been started or has clients bound to it

• If the service is currently executing code in its onCreate(), onStartCommand(), or onDestroy() methods, then the hosting process will be a foreground process to ensure this code can execute without being killed.

Page 30: Mobile Programming Lecture 8

Service - Forms of a ServiceA service can take 2 forms

• A Started Service is one where an application component (such as an Activity) starts it by calling startService()o it can then run in the background indefinitely, even if the component that

started it has been destroyedo onStartCommand() allows it to start

• A Bound Service is one where an application component binds to it by calling bindService()o it then offers a client-server interface that allows components to interact with ito a bound service runs only as long as an another application component is

bound to ito multiple component can bind to the service at the same timeo onBind() allows binding on the Service

Page 31: Mobile Programming Lecture 8

Service - LifeCycle

This is important

Page 32: Mobile Programming Lecture 8

Service - LifeCyclein either case ...

• onCreate()o not called if Service is already running

• onStartCommand()o service now started and can run in background indefinitely

• onDestroy()o Service is no longer in use and is being destroyed

Page 33: Mobile Programming Lecture 8

Adding a Service to your Project

• Open AndroidManifest.xml• Click on the Application Tab• Under Application Nodes, click Add ...• Select Service• Under Attributes for Service, click on Name*• Enter the name of your Service, e.g.

MyService• Your class may be underlined in red, mouse

over it and choose Add unimplemented methods

Page 34: Mobile Programming Lecture 8

Creating a Started Service

Override the Service method:

public int onStartCommand(Intent, int, int)

• to stop the Service (you should when it's job is done)o the Service should stop itself by calling stopSelf() when it's job is

done

• another component can call stopService(Intent)

Page 35: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyActivity extends Activity {

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

myIntent = new Intent(this, MyService.class);startService(myIntent);

}}

Page 36: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyActivity extends Activity {

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

myIntent = new Intent(this, MyService.class);startService(myIntent);

}}

Here we start with an Activity

Page 37: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyActivity extends Activity {

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

myIntent = new Intent(this, MyService.class);startService(myIntent);

}}

Looks familiar? Starting a Service is almost the same as starting an Activity

Page 38: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyActivity extends Activity {

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

myIntent = new Intent(this, MyService.class);startService(myIntent);

}}

We call startService() instead of startActivity() thoguh

Page 39: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyService extends Service {

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

Log.i(TAG, "Service.onStartCommand()");

final int LIMIT = 10;

int i;

// do nothing for LIMIT iterations

for(i = 0; i < LIMIT; i++) ;

stopSelf();

return Service.START_STICKY;

}

}

Here we extend Service

Page 40: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyService extends Service {

@Override public int onStartCommand(Intent intent, int flags, int startId) {

Log.i(TAG, "Service.onStartCommand()");

final int LIMIT = 10;

int i;

// do nothing for LIMIT iterations

for(i = 0; i < LIMIT; i++) ;

stopSelf();

return Service.START_STICKY;

}

}

We override onStartCommand(), which is called each time startService() is called

Page 41: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyService extends Service {

@Override

public int onStartCommand(Intent intent, int flags, int startId) {Log.i(TAG, "Service.onStartCommand()");

final int LIMIT = 10;

int i;

// do nothing for LIMIT iterations

for(i = 0; i < LIMIT; i++) ;

stopSelf();

return Service.START_STICKY;

}

}

Note the semicolon. This for loop is empty and is just there to simulate the Service doing some work

Page 42: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyService extends Service {

@Override

public int onStartCommand(Intent intent, int flags, int startId) {Log.i(TAG, "Service.onStartCommand()");

final int LIMIT = 10;

int i;

// do nothing for LIMIT iterations

for(i = 0; i < LIMIT; i++) ;

stopSelf();

return Service.START_STICKY;

}

}

The Service is done so it stops itself

Page 43: Mobile Programming Lecture 8

Creating a Started Servicepublic class MyService extends Service {

@Override

public int onStartCommand(Intent intent, int flags, int startId) {Log.i(TAG, "Service.onStartCommand()");

final int LIMIT = 10;

int i;

// do nothing for LIMIT iterations

for(i = 0; i < LIMIT; i++) ;

stopSelf();

return Service.START_STICKY;}

}

onStartCommand() must return a value, although this return value may be useless here since we called stopSelf()

Page 44: Mobile Programming Lecture 8

Creating a Started Service

See ServiceLifeCycleExample.tar

Page 45: Mobile Programming Lecture 8

Creating a Started ServiceonStartCommand() return values

• START_STICKYo if this service's process is killed while it is started (after returning from

onStartCommand() ), then leave it in the started state.o This is suitable for media players (or similar services) that are not

executing commands, but running indefinitely and waiting for a job

• START_NOT_STICKYo if this service's process is killed while it is started, then take the

service out of the started state and don't recreate.

• START_REDELIVER_INTENTo if this service's process is killed while it is started (after returning from

onStartCommand()), then it will be scheduled for a restart and the last delivered Intent re-delivered to it

Page 46: Mobile Programming Lecture 8

Creating a Started Service

To create a started service, you can either extend Service or IntentService

• Serviceo it uses your main application's thread by default and

can slow down your app you should create a new thread for the Service to

work in if it slows down your app

• IntentServiceo ...

Page 47: Mobile Programming Lecture 8

IntentService

If you don't want to create a separate thread yourself, you can extend IntentService, which

•creates a default worker thread that executes all intents delivered to onStartCommand() separate from your application's main thread

•creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading.

•stops the service after all start requests have been handled, so you never have to call stopSelf().

•provides default implementation of onBind() that returns null.•provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation.

Page 48: Mobile Programming Lecture 8

IntentService

In other words

• You really only need a o constructoro to override onHandleIntent(Intent)

If you decide to override onCreate() or onStartCommand() or onDestroy() anyway, then you should call super.on_()

Page 49: Mobile Programming Lecture 8

IntentServicepublic class MyService extends IntentService {

private static final String TAG = "ServiceExample";

public MyService() {super("MyService");

}

@Overrideprotected void onHandleIntent(Intent intent) {

final int LIMIT = 200000000;int i;

for(i = 0; i < LIMIT; i++) ;}

}

Page 50: Mobile Programming Lecture 8

Communicating with a Service

• Typically you would like to tell the application about events that occurs inside a service.

• The service client (e.g. Activity) can provide some sort of “callback” or “listener” object to the service, which the service could then call when needed.

Page 51: Mobile Programming Lecture 8

Communicating with a Service

Here are several ways that you can have your client communicate with your Service

1. Broadcast Intent2. Pending Result3. Messenger

Page 52: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

1. BroadcastIntent Example

This code example involves these components

• Activity

• Service

• BroadcastReceiver

Page 53: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyActivity extends Activity {

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent sIntent = new Intent(getApplicationContext(), MyService.class);sIntent.putExtra("myaction", "loop");startService(sIntent);

}});

}}

Here we start with an Activity

Page 54: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyActivity extends Activity {

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent sIntent = new Intent(getApplicationContext(), MyService.class);sIntent.putExtra("myaction", "loop");startService(sIntent);

}});

}}

Add some extra information to the Intent so that the Service can know which job to perform

Page 55: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 1000000000;Bundle extras = intent.getExtras();

if(extras != null){

if(extras.getString("myaction").equals("loop"))for(i = 0; i < LIMIT; i++);

}

Intent myIntent = new Intent(this, MyReceiver.class);sendBroadcast(myIntent);

}}

Here we extend IntentService instead of Service

Page 56: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 1000000000;Bundle extras = intent.getExtras();

if(extras != null){

if(extras.getString("myaction").equals("loop"))for(i = 0; i < LIMIT; i++);

}

Intent myIntent = new Intent(this, MyReceiver.class);sendBroadcast(myIntent);

}}

In doing so, you must have a constructor

Page 57: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 1000000000;Bundle extras = intent.getExtras();

if(extras != null){

if(extras.getString("myaction").equals("loop"))for(i = 0; i < LIMIT; i++);

}

Intent myIntent = new Intent(this, MyReceiver.class);sendBroadcast(myIntent);

}}

and we override onHandleIntent() instead of onStartCommand()

Page 58: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 1000000000;Bundle extras = intent.getExtras();

if(extras != null){

if(extras.getString("myaction").equals("loop"))for(i = 0; i < LIMIT; i++);

}

Intent myIntent = new Intent(this, MyReceiver.class);sendBroadcast(myIntent);

}}

Get the extras out of the intent, and let's see if we're tasked to loop

Page 59: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 1000000000;Bundle extras = intent.getExtras();

if(extras != null){

if(extras.getString("myaction").equals("loop"))for(i = 0; i < LIMIT; i++);

}

Intent myIntent = new Intent(this, MyReceiver.class);sendBroadcast(myIntent);

}}

If so, then let's do some work!

Page 60: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 1000000000;Bundle extras = intent.getExtras();

if(extras != null){

if(extras.getString("myaction").equals("loop"))for(i = 0; i < LIMIT; i++);

}

Intent myIntent = new Intent(this, MyReceiver.class);sendBroadcast(myIntent);

}}

This is just an example of how to send a task to a Service. You can do this with by extending Service as well as IntentService

Page 61: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 1000000000;Bundle extras = intent.getExtras();

if(extras != null){

if(extras.getString("myaction").equals("loop"))for(i = 0; i < LIMIT; i++);

}

Intent myIntent = new Intent(this, MyReceiver.class);sendBroadcast(myIntent);

}}

Let's intend on making an explicit broadcast

Page 62: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 1000000000;Bundle extras = intent.getExtras();

if(extras != null){

if(extras.getString("myaction").equals("loop"))for(i = 0; i < LIMIT; i++);

}

Intent myIntent = new Intent(this, MyReceiver.class);sendBroadcast(myIntent);

}}

Send the broadcast and ...

Page 63: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyReceiver extends BroadcastReceiver {

@Overridepublic void onReceive(Context context, Intent intent) {

Toast.makeText(context,

"Broadcast Received, Work Completed",Toast.LENGTH_LONG)

.show();}

}

Voila! We had a BroadcastReceiver set up already of course

Page 64: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyReceiver extends BroadcastReceiver {

@Overridepublic void onReceive(Context context, Intent intent) {

Toast.makeText(context,

"Broadcast Received, Work Completed",Toast.LENGTH_LONG)

.show();}

}

In here we can take whatever action we want to.

Page 65: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyReceiver extends BroadcastReceiver {

@Overridepublic void onReceive(Context context, Intent intent) {

Toast.makeText(context,

"Broadcast Received, Work Completed",Toast.LENGTH_LONG)

.show();}

}

The Service could have added extras to the Intent to give us more information

Page 66: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyReceiver extends BroadcastReceiver {

@Overridepublic void onReceive(Context context, Intent intent) {

Toast.makeText(context,

"Broadcast Received, Work Completed",Toast.LENGTH_LONG)

.show();}

}

Depending on that, we may want to take some action such as give a Notification

Page 67: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

public class MyReceiver extends BroadcastReceiver {

@Overridepublic void onReceive(Context context, Intent intent) {

Toast.makeText(context,

"Broadcast Received, Work Completed",Toast.LENGTH_LONG)

.show();}

}Or do nothing at all

Page 68: Mobile Programming Lecture 8

Communicating with a Service - 1. Broadcast Intent

See ServiceBroadcastIntent.tar

Page 69: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

2. PendingResult Example

This code example involves the following components

• Activity• Service

Page 70: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

Remember, the reason for a PendingIntent is to allow a different app to fulfill an Intent on our behalf

Page 71: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

PendingIntent contentIntent = createPendingResult(15, new Intent(), 0); final Intent sIntent = new Intent(this, MyService.class);sIntent.putExtra("pending",contentIntent);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Override public void onClick(View v) {startService(sIntent);

}});

}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {...

}}

Starting with our Activity

Page 72: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

PendingIntent contentIntent = createPendingResult(15, new Intent(), 0); final Intent sIntent = new Intent(this, MyService.class);sIntent.putExtra("pending",contentIntent);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Override public void onClick(View v) {startService(sIntent);

}});

}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {...

}}

We call Activity.createPendingResult, which returns a PendingIntent

Page 73: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

PendingIntent contentIntent = createPendingResult(15, new Intent(), 0); final Intent sIntent = new Intent(this, MyService.class);sIntent.putExtra("pending",contentIntent);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Override public void onClick(View v) {startService(sIntent);

}});

}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {...

}}

When the result is returned out our Activity, we want to identify our task using the number 15 (any number you to distinguish between results)

Page 74: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

PendingIntent contentIntent = createPendingResult(15, new Intent(), 0); final Intent sIntent = new Intent(this, MyService.class);sIntent.putExtra("pending",contentIntent);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Override public void onClick(View v) {startService(sIntent);

}});

}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {...

}}

We create an Intent that can start a Service

Page 75: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

PendingIntent contentIntent = createPendingResult(15, new Intent(), 0); final Intent sIntent = new Intent(this, MyService.class);sIntent.putExtra("pending",contentIntent);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Override public void onClick(View v) {startService(sIntent);

}});

}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {...

}}

We package our PendingIntent inside of our Service Intent, so that the Service can use it on our behalf

Page 76: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

PendingIntent contentIntent = createPendingResult(15, new Intent(), 0); final Intent sIntent = new Intent(this, MyService.class);sIntent.putExtra("pending",contentIntent);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Override public void onClick(View v) {startService(sIntent);

}});

}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {...

}}

Let's go ahead and start the Service whenever a Button is clicked

Page 77: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);

PendingIntent contentIntent = createPendingResult(15, new Intent(), 0); final Intent sIntent = new Intent(this, MyService.class);sIntent.putExtra("pending",contentIntent);

Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Override public void onClick(View v) {startService(sIntent);

}});

}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

... }

}

We will get back to this method soon shortly

Page 78: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 500000000;

for(i = 0; i < LIMIT; i++);

PendingIntent pIntent = (PendingIntent) intent.getParcelableExtra("pending");

try {pIntent.send(1);

} catch (CanceledException e) {e.printStackTrace();

}}

}

Here's our Service!

Page 79: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 500000000;

for(i = 0; i < LIMIT; i++);

PendingIntent pIntent = (PendingIntent) intent.getParcelableExtra("pending");

try {pIntent.send(1);

} catch (CanceledException e) {e.printStackTrace();

}}

}

This get's called because the Button in the Activity was clicked, which then called startService()

Page 80: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 500000000;

for(i = 0; i < LIMIT; i++);

PendingIntent pIntent = (PendingIntent) intent.getParcelableExtra("pending");

try {pIntent.send(1);

} catch (CanceledException e) {e.printStackTrace();

}}

}

Remember the PendingIntent that was packaged? Let's get it!

Page 81: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 500000000;

for(i = 0; i < LIMIT; i++);

PendingIntent pIntent = (PendingIntent) intent.getParcelableExtra("pending");

try {pIntent.send(1);

} catch (CanceledException e) {e.printStackTrace();

}}

}

Let's try sending a result (1 in this case) back to the Activity

Page 82: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 500000000;

for(i = 0; i < LIMIT; i++);

PendingIntent pIntent = (PendingIntent) intent.getParcelableExtra("pending");

try {pIntent.send(1);

} catch (CanceledException e) {e.printStackTrace();

}}

}

This works because this PendingIntent was created in our Activity using createPendingResult()

Page 83: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {

int i;int LIMIT = 500000000;

for(i = 0; i < LIMIT; i++);

PendingIntent pIntent = (PendingIntent) intent.getParcelableExtra("pending");

try {pIntent.send(1);

} catch (CanceledException e) {e.printStackTrace();

}}

}

So where does the code go from here (if there are no Exceptions of course)

Page 84: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

...}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 15) {

if(resultCode == 1)Toast.makeText(this, "Result is GOOD", Toast.LENGTH_SHORT).show()

elseToast.makeText(this, "Result is BAD", Toast.LENGTH_SHORT).show()

}}

}

Voila, back to our Activity, Activity.onActivityResult() specifically

Page 85: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

...}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 15) {

if(resultCode == 1)Toast.makeText(this, "Result is GOOD", Toast.LENGTH_SHORT).show()

elseToast.makeText(this, "Result is BAD", Toast.LENGTH_SHORT).show()

}}

}

This is a callback method, which means that the system calls this method if you have it define

Page 86: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

...}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 15) {

if(resultCode == 1)Toast.makeText(this, "Result is GOOD", Toast.LENGTH_SHORT).show()

elseToast.makeText(this, "Result is BAD", Toast.LENGTH_SHORT).show()

}}

}

See it here

Page 87: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

...}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 15) {

if(resultCode == 1)Toast.makeText(this, "Result is GOOD", Toast.LENGTH_SHORT).show()

elseToast.makeText(this, "Result is BAD", Toast.LENGTH_SHORT).show()

}}

}

requestCode should already be set to 15, because that's the number we passed as argument to createPendingResult()

Page 88: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

...}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 15) {

if(resultCode == 1)Toast.makeText(this, "Result is GOOD", Toast.LENGTH_SHORT).show()

elseToast.makeText(this, "Result is BAD", Toast.LENGTH_SHORT).show()

}}

}

resultCode should already be set to 1, because the Service set this value using PendingIntent.send()

Page 89: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

...}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 15) {

if(resultCode == 1)Toast.makeText(this, "Result is GOOD", Toast.LENGTH_SHORT).show()

elseToast.makeText(this, "Result is BAD", Toast.LENGTH_SHORT).show()

}}

}

The Service could have possible added extra information to the Intent that was provided in Service.onHandleIntent (although we didn't do so in this example)

Page 90: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

...}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 15) {

if(resultCode == 1)Toast.makeText(this, "Result is GOOD", Toast.LENGTH_SHORT).show()

elseToast.makeText(this, "Result is BAD", Toast.LENGTH_SHORT).show()

}}

}

Let's make sure that this is our request and not some other request that we made (we made no other requests in this example)

Page 91: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

public class MyActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

...}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 15) {

if(resultCode == 1)Toast.makeText(this, "Result is GOOD", Toast.LENGTH_SHORT).show()

elseToast.makeText(this, "Result is BAD",

Toast.LENGTH_SHORT).show()

}}

}

If the Service called PendingIntent.send() with any value other than 1, then we choose to treat it as an error (you can treat it however you want to)

Page 92: Mobile Programming Lecture 8

Communicating with a Service - 2. Pending Result

See ServicePendingResult.tar

Page 93: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

3. Messenger

Page 94: Mobile Programming Lecture 8

• A Messenger sends messages to an activity’s Handler

• Use the Messenger as the bridge between an Activity

and a Service

• A Messenger is Parcelable!

o Which means it can be put into an Intent extra.

• The Activity calling startService() would attach a

Messenger as an extra in the Intent

• The Service would obtain that Messenger from the

Intent

Communicating with a Service - 3. Messenger

Page 95: Mobile Programming Lecture 8

When the service wants to tell the activity about some event that just occurred, it would:

o Call Message.obtain() to get an empty Message object Message msg = Message.obtain();

o Populate that Message object with whatever data the service wishes to pass to the activity. int result = Activity.RESULT_CANCELED; msg.arg1 = result;

o Call send() on the Messenger, supplying the Message as a parameter messenger.send(msg);

o The activity’s Handler object will receive the message via handleMessage(). This will be on the main application thread so that updates to the

UI or whatever you would like can happen.

Communicating with a Service - 3. Messenger

Page 96: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

3. Messenger Example

This code example involves the following components

• Activity• Service

Page 97: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

Page 98: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

Let's start with our Activity

Page 99: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

We create another class inside of our Activity! We'll get back to this shortly

Page 100: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

For now, just note that we reference it as handler

Page 101: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

Let's take some action after a Button is clicked

Page 102: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

So we want to start a Service at some point

Page 103: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

And we'er adding some Messenger Object to our Bundle, hmm ...

Page 104: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

And we'er adding some Messenger Object to our Bundle, hmm ...

Page 105: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

Let's start our Service and see what happens

Page 106: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

Here's our Service

Page 107: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

Nothing new here, this gets called because we started the IntentService

Page 108: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

Try to get a Bundle

Page 109: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

Make sure it's not null. If it's null and you try you use it you'll get Force Close

Page 110: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

We can get the Messenger that was passed via the Bundle!

Page 111: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

Let's create a new Message. Message.obtain() is nothing super special here, it just returns a new Message() object more efficiently

Page 112: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

This Bundle is DIFFERENT than the one we got using intent.getExtras()

Page 113: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

We had a boolean value to the results Bundle

Page 114: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

We add the Bundle to the Message (not the Messenger)!

Page 115: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyService extends IntentService {public MyService() {

super("MyService");}

@Override protected void onHandleIntent(Intent intent) {for(int i = 0; i < 50000000; i++);

Bundle extras = intent.getExtras();if(extras != null) {

Messenger messenger = (Messenger) extras.get("messenger");Message msg = Message.obtain();Bundle results = new Bundle();results.putBoolean("success", true);msg.setData(results);try {

messenger.send(msg);} catch (RemoteException e) {

e.printStackTrace();}

}

}}

Let's try sending the Message via the Messenger. Where does the code go from here?

Page 116: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

To the handleMessage() callback function of the Handler!

Page 117: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

Remember we passed handler as an argument to the Messenger object

Page 118: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

And we packaged the Messenger in our Intent

Page 119: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

That Intent was used to start our Service

Page 120: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

And the Service added a Message to the Messenger, and then sent the Message

Page 121: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

That Message was received by handler

Page 122: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

The handler can now get the Message, which is packaged in a Bundle

Page 123: Mobile Programming Lecture 8

Communicating with a Service - 3. Messenger

public class MyActivity extends Activity {private Handler handler = new Handler() {

@Override public void handleMessage(Message msg) {Bundle results = msg.getData();if(results.getBoolean("success") == true) Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();

}};

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent myIntent = new Intent(MyActivity.this, MyService.class);myIntent.putExtra("messenger", new Messenger(handler));startService(myIntent);

}});

}}

Note that the reason we can pass an instance of Messenger to Intent.puExtra() is because Messenger is Parcelable

Page 124: Mobile Programming Lecture 8

DownloadService

This example from Mark Murphy uses• Activity• Service• Messenger

to download a file, given a URL

See DownloaderServiceExample.tar

Page 125: Mobile Programming Lecture 8

DownloadManager

• DownloadManager is available in 2.3 and higher (API Level 9)o Use this instead of DownloadService if you have a

device that supports this

See DownloadManagerExample.tar

• This example by Lars Vogel uses a single Activity

Page 126: Mobile Programming Lecture 8

MediaPlayer

The Android MediaPlayer class allows you to play songs and video

It is not an Activity, but can be used by an Activity or Service

Page 127: Mobile Programming Lecture 8

MediaPlayer

There are several ways you can playback music using a MediaPlayer

We'll only be looking at playing back from some location on our devices

Page 128: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();

}

}

Page 129: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();

}

}

A simple Activity

Page 130: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();

}

}

You're provided with a convenient way to create a MediaPlayer by passing it a resource id

Page 131: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();

}

}

Here I took an MP3 file named palace.mp3, created the directory res/raw, and placed the MP3 in said directory

Page 132: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();

}

}

res/raw is another special Android directory, used for general-purpose files (e.g,. an audio clip, a CSV file ofaccount information)

Page 133: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start(); for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();

}

}

Start playing the MP3, so simple

Page 134: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();

}

}

Wait for some time to elapse ...

Page 135: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();

}

}

Try to go back to the beginning of the track

Page 136: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;mp.stop();

mp.release();

}

}

Wait for some time to elapse

Page 137: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();mp.release();

}

}

Stop playback

Page 138: Mobile Programming Lecture 8

MediaPlayer - Examplepublic class MediaPlayerExampleActivity extends Activity {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

MediaPlayer mp = MediaPlayer.create(this, R.raw.palace);

mp.start();

for(int i = 0; i < 100000000; i++) ;

try{

mp.seekTo(0);

} catch (IllegalStateException e) { }

for(int i = 0; i < 50000000; i++) ;

mp.stop();

mp.release();}

}

Free up the resources! This is important to performance (battery life!)

Page 139: Mobile Programming Lecture 8

State Diagram of MediaPlayer

Page 140: Mobile Programming Lecture 8

AsyncTask• enables proper and easy use of the UI thread

• the main thread in Android is the UI thread

• the actions in the UI thread are queued!o when you press a Button, it has to be redrawn on the screeno pressing another Button before the previous is redrawn will queue

• allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

Page 141: Mobile Programming Lecture 8

AsyncTask looks a bit awkward ...Because it uses Generic Types

• 3 generic types are required when extending AsyncTasko The three types used by an asynchronous task are

the following:1. Params, the type of the parameters sent to the task

upon execution2. Progress, the type of the progress units published

during the background computation3. Result, the type of the result of the background

computation

Page 142: Mobile Programming Lecture 8

AsyncTask - 4 stepsWhen an asynchronous task is executed, the task goes through 4 steps

1. onPreExecute(), invoked on the UI thread immediately after the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.

2. doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also usepublishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step

3. onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field

4. onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.

Page 143: Mobile Programming Lecture 8

AsyncTask - 4 steps

See AsyncTaskFullExample.tar