33
CSS216 MOBILE PROGRAMMING Android, Chapter 9 Book: “Professional Android™ 2 Application Development” by Reto Meier, 2010 by: Andrey Bogdanchikov ( [email protected] )

CSS216 MOBILE PROGRAMMING Android, Chapter 9 Book: “Professional Android™ 2 Application Development” by Reto Meier, 2010 by: Andrey Bogdanchikov ( [email protected]

Embed Size (px)

Citation preview

CSS216 MOBILE PROGRAMMING

Android, Chapter 9

Book: “Professional Android™ 2 Application Development” by Reto Meier, 2010

by: Andrey Bogdanchikov ( [email protected] )

Outline(Working in the Background)• Creating, starting, and stopping Services• Binding Services to Activities• Setting Service priority to foreground• Using AsyncTasks to manage background processing• Creating background threads and using Handlers to

synchronize with the GUI thread• Displaying Toasts• Using the Notification Manager to notify users of application

events• Creating insistent and ongoing Notifications• Using Alarms to schedule application events

Introduction• Android offers the Service class to create application

components specifically to handle operations and functionality that should run invisibly, without a user interface.

• Android accords Services a higher priority than inactive Activities, so they’re less likely to be killed when the system requires resources. In fact, should the run time prematurely terminate a Service that’s been started, it can be configured to restart as soon as sufficient resources become available.

• By using Services, you can ensure that your applications continue to run and respond to events, even when they’re not in active use.

• Services run without a dedicated GUI, but, like Activities and Broadcast Receivers, they still execute in the main thread of the application’s process.

• To help keep your applications responsive, you’ll learn to move time-consuming processes (like network lookups) into background threads using the Thread and AsyncTask classes.

• Android offers several techniques for applications to communicate with users without an Activity.

• You’ll learn how to use Notifications and Toasts or alert and update users without interrupting the active application.

Introducing services• Unlike Activities, which present a rich graphical interface to

users, Services run in the background — updating your Content Providers, firing Intents, and triggering Notifications.

• They are the perfect means of performing ongoing or regular processing and of handling events even when your application’s Activities are invisible or inactive, or have been closed.

• Services are started, stopped, and controlled from other application components, including other Services, Activities, and Broadcast Receivers.

• If your application performs actions that don’t depend directly on user input, Services may be the answer.

• Started Services always have higher priority than inactive or invisible Activities, making them less likely to be terminated by the run time’s resource management. The only reason Android will stop a Service prematurely is to provide additional resources for a foreground component (usually an Activity). When that happens, your Service will be restarted automatically when resources become available.

• If your Service is interacting directly with the user (for example, by playing music) it may be necessary to increase its priority to that of a foreground Activity. This will ensure that your Service isn’t terminated except in extreme circumstances.

Creating a Servicepublic class MyService extends Service {

@Overridepublic void onCreate() {

// TODO: Actions to perform when service is created.

}@Overridepublic IBinder onBind(Intent intent) {

// TODO: Replace with service binding implementation.

return null;}

}

• In most cases you’ll also want to override onStartCommand. • This is called whenever the Service is started with a call to

startService, so it may be executed several times within a Service’s lifetime. You should ensure that your Service accounts for this.

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Launch a background thread to do processing.

return Service.START_STICKY;

}

Registering a Service in the Manifest

• Once you’ve constructed a new Service, you have to register it in the application manifest.

• Do this by including a <service> tag within the application node. Use the requires-permission attribute to require a uses-permission for other applications to access this Service.

• The following is the service tag you’d add for the skeleton Service you created earlier:

<service android:enabled="true" android:name=".MyService"/>

Self-Terminating a Service• Once your Service has completed the actions or processing

it was started for, you should make a call to stopSelf, either without a parameter to force a stop, or by passing in a startId value to insure processing has been completed for each instance of startService called so far, as shown in the following snippet:

stopSelf(startId);• By explicitly stopping the Service when your processing is

complete, you allow the system to recover the resources otherwise required to keep it running.

Starting, Controlling, and Interacting with a Service

// Implicitly start a ServiceIntent myIntent = new Intent(MyService.ORDER_PIZZA);

myIntent.putExtra("TOPPING", "Margherita");startService(myIntent);// Explicitly start a ServicestartService(new Intent(this, MyService.class));

Stopping a ServiceComponentName service = startService(new Intent(this,

BaseballWatch.class));

// Stop a service using the service name.

stopService(new Intent(this, service.getClass()));

// Stop a service explicitly.

try {Class serviceClass = Class.forName(service.getClassName());

stopService(new Intent(this, serviceClass));

} catch (ClassNotFoundException e) {}

Using background threads• To ensure that your applications remain responsive, it’s good

practice to move all slow, time-consuming operations off the main application thread and onto a child thread.• All Android application components — including Activities, Services,

and Broadcast Receivers — start on the main application thread. As a result, time-consuming processing in any component will block all other components including Services and the visible Activity.

• Android offers two alternatives for backgrounding your processing. • The AsyncTask class lets you define an operation to be

performed in the background, then provides event handlers you can use to monitor progress and post the results on the GUI thread.

• Alternatively, you can implement your own Threads and use the Handler class to synchronize with the GUI thread before updating the UI.

Creating a new Asynchronous Taskprivate class MyAsyncTask extends AsyncTask<String, Integer,

Integer> {@Override

protected void onProgressUpdate(Integer... progress) {

}

@Override

protected void onPostExecute(Integer... result) {

}

@Override

protected Integer doInBackground(String... parameter) {int myProgress = 0;

// [... Perform background processing task, update myProgress ...]

PublishProgress(myProgress)

// [... Continue performing background processing task ...]

// Return the value to be passed to onPostExecute

return result;

}

}

StructureAs shown in previous Listing, your subclass should implement the

following event handlers:

➤ doInBackground Takes a set of parameters of the type defined in your class implementation.

➤ onProgressUpdate Override this handler to post interim updates to the UI thread. This handler receives the set of parameters passed in to publishProgress from within doInBackground. This handler is synchronized with the GUI thread when executed, so you can safely modify UI elements.

➤ onPostExecute When doInBackground has completed, the return value from that method is passed in to this event handler. Use this handler to update the UI once your asynchronous task has completed. This handler is synchronized with the GUI thread when executed, so you can safely modify UI elements.

Executing an asynchronous task

new MyAsyncTask().execute("inputString1", "inputString2");

• Each AsyncTask instance can be executed only once. If you attempt to call execute a second time an exception will be thrown.

Let’s make a toast!

• Toasts are transient Dialog boxes that remain visible for only a few seconds before fading out. Toasts don’t steal focus and are non-modal, so they don’t interrupt the active application.

• Toasts are perfect for informing your users of events without forcing them to open an Activity or read a Notification.

• They provide an ideal mechanism for alerting users to events occurring in background Services without interrupting foreground applications.

Displaying a Toast

Context context = getApplicationContext();String msg = "To health and happiness!";int duration = Toast.LENGTH_SHORT;Toast toast = Toast.makeText(context, msg, duration);

toast.show();

Customizing a Toast

Context context = getApplicationContext();String msg = "To the bride and groom!";int duration = Toast.LENGTH_SHORT;Toast toast = Toast.makeText(context, msg, duration);int offsetX = 0;int offsetY = 0;toast.setGravity(Gravity.BOTTOM, offsetX, offsetY);

toast.show();

Introducing notifications• Your applications can use Notifications to alert users without

using an Activity. Notifications are handled by the Notification Manager, and currently have the ability to:• Create new status bar icons• Display additional information (and launch an Intent) in the

extended status bar window• Flash the lights/LEDs• Vibrate the phone• Sound audible alerts (ringtones, Media Store audio)

User and device• Using Notifications is the preferred way for invisible

application components (Broadcast Receivers, Services, and inactive Activities) to alert users that events have occurred that may require attention. They are also used to indicate ongoing background Services — particularly Services that have been set to foreground priority.

• As a user interface metaphor, Notifications are particularly well suited to mobile devices. It’s likely that your users will have their phones with them at all times but quite unlikely that they will be paying attention to them, or your application, at any given time. Generally users will have several applications open in the background, and they won’t be paying attention to any of them.

Introducing the Notification Manager

• The Notification Manager is a system Service used to handle Notifications. Get a reference to it using the getSystemService method.

String svcName = Context.NOTIFICATION_SERVICE;NotificationManager notificationManager;notificationManager = (NotificationManager)getSystemService(svcName);

Creating Notifications• Android offers a number of ways to convey information to

users using Notifications.• 1. The status bar icon• 2. The extended notification status drawer• 3. Additional phone effects such as sound and vibration

• This section will examine the first two while later in this chapter you’ll learn how to enhance Notifications using various properties on the Notification object to flash the device LEDs, vibrate the phone, and play audio.

Creating a Notification and Configuring the Status Bar Icon

// Choose a drawable to display as the status bar iconint icon = R.drawable.icon;// Text to display in the status bar when the notification is launched

String tickerText = "Notification";// The extended status bar orders notification in time order

long when = System.currentTimeMillis();Notification notification = new Notification(icon, tickerText, when);

Configuring the Extended Status Notification Display

• You can configure the appearance of the Notification within the extended status window in two ways:• 1. Use the setLatestEventInfo method to update the details

displayed in the standard extended status Notification display.• 2. Set the contentView and contentIntent properties to assign a

custom UI for the extended status display using a Remote View.

• The simplest technique is to use the setLatestEventInfo method to populate the default status window layout. The standard extended status window layout shows the icon and time defined in the constructor, along with a title and a details string

Advanced Notification Techniques

• In the following sections you’ll learn to enhance Notifications to provide additional alerting through hardware, particularly by making the device ring, flash, and vibrate.

Using the Defaults• The simplest and most consistent way to add sound, light,

and vibration to your Notifications is to use the current user default settings. Using the defaults property you can combine:• ➤ Notification.DEFAULT_LIGHTS• ➤ Notification.DEFAULT_SOUND• ➤ Notification.DEFAULT_VIBRATE

• The following code snippet assigns the default sound and vibration settings to a Notification:

notification.defaults = Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE;

• If you want to use all the default values you can use the Notification.DEFAULT_ALL constant.

Making Sounds• Using an audio alert to notify the user of a device event

(like incoming calls) is a technique that predates the mobile, and has stood the test of time. Most native phone events, from incoming calls to new messages and low battery, are announced by audible ringtones.

if (quake.getMagnitude() > 6) {Uri ringURI =RingtoneManager.getDefaultUri(RingtoneManager.TYPE_N

OTIFICATION);newEarthquakeNotification.sound = ringURI;

}

Using alarms• Alarms are an application-independent means of firing

Intents at predetermined times and intervals. • Alarms are set outside the scope of your applications, so

they can be used to trigger application events or actions even after your application has been closed.

• They can be particularly powerful in combination with Broadcast Receivers, enabling you to set Alarms that fire Broadcast Intents, start Services, or even open Activities, without the applications’ needing to be open or running until they’re required.

Create

• Alarm operations are handled through the AlarmManager, a system Service accessed via getSystemService, as shown here:

AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);

• To create a new one-shot Alarm, use the set method and specify an alarm type, a trigger time, and a Pending Intent to fire when the Alarm triggers.

• If the trigger time you specify for the Alarm occurs in the past, the Alarm will be triggered immediately.

Types• There are four alarm types available. Your selection will

determine if the time value passed in the set method represents a specific time or an elapsed wait:• ➤ RTC_WAKEUP Wake the device from sleep to fire the Pending Intent

at the clock time specified.• ➤ RTC Fire the Pending Intent at the time specified, but do not wake the

device.• ➤ ELAPSED_REALTIME Fire the Pending Intent based on the amount

of time elapsed since the device was booted, but do not wake the device. The elapsed time includes any period of time the device was asleep. Note that the time elapsed is calculated based on when the device was last booted.

• ➤ ELAPSED_REALTIME_WAKEUP After a specified length of time has passed since device boot, wake the device from sleep and fire the Pending Intent.

Creating an Alarmint alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;

long timeOrLengthofWait = 10000;

String ALARM_ACTION = "ALARM_ACTION";

Intent intentToFire = new Intent(ALARM_ACTION);

PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0);

alarms.set(alarmType, timeOrLengthofWait, pendingIntent);

THE ENDThank you