2011年5月18日水曜日

AndroidStudyMemo=Notifying

Notifying with the Status Bar

The standard location for displaying notifications and indicators on an Android device is

the status bar that runs along the top of the screen.Typically, the status bar shows information

such as the current date and time. It also displays notifications (like incoming SMS

messages) as they arrive?in short form along the bar and in full if the user pulls down the

status bar to see the notification list.The user can clear the notifications by pulling down

the status bar and hitting the Clear button.

 

Developers can enhance their applications by using notifications from their applications

to inform the user of important events. For example, an application might want to send a

simple notification to the user whenever new content has been downloaded.A simple

notification has a number of important components:

An icon (appears on status bar and full notification)

Ticker text (appears on status bar)

Notification title text (appears in full notification)

Notification body text (appears in full notification)

An intent (launches if the user clicks on the full notification)

 

In this section, you learn how to create this basic kind of notification.

 

 

Using the NotificationManager Service

All notifications are created with the help of the NotificationManager.The

NotificationManager (within the android.app package) is a system service that must be

requested.The following code demonstrates how to obtain a valid NotificationManager

object using the getSystemService() method:

              NotificationManager notifier = (NotificationManager)

                            getSystemService(Context.NOTIFICATION_SERVICE);

 

The NotificationManager is not useful without having a valid Notification object to

use with the notify() method.The Notification object defines what information displays

to the user when the Notification is triggered.This includes text that displays on

the status bar, a couple of lines of text that display on the expanded status bar, an icon displayed

in both places, a count of the number of times this Notification has been triggered,

and a time for when the last event that caused this Notification took place.

 

Creating a Simple Text Notification with an Icon

You can set the icon and ticker text, both of which display on the status bar, through the

constructor for the Notification object, as follows:

              Notification notify = new Notification(

                            R.drawable.android_32, "Hello!", System.currentTimeMillis());

 

Additionally, you can set notification information through public member variable

assignment, like this:

              notify.icon = R.drawable.android_32;

              notify.tickerText = "Hello!";

              notify.when = System.currentTimeMillis();

 

You need to set a couple more pieces of information before the call to the notify()

method takes place. First,we need to make a call to the setLastEventInfo() method,

which configures a View that displays in the expanded status bar. Here is an example:

              Intent toLaunch = new Intent

                            (SimpleNotificationsActivity.this,

                                          SimpleNotificationsActivity.class);

              PendingIntent intentBack = PendingIntent.getActivity

                            (SimpleNotificationsActivity.this, 0, toLaunch, 0);

              notify.setLatestEventInfo(SimpleNotificationsActivity.this,

                            "Hi there!", "This is even more text.", intentBack);

 

Next, use the notify() method to supply the notification's title and body text as well as

the Intent triggered when the user clicks on the notification. In this case,we're using our

own Activity so that when the user clicks on the notification, our Activity launches

again.

 

 

Working with the Notification Queue

Now the application is ready to actually notify the user of the event. All that is needed is a

call to the notify() method of the NotificationManager with an identifier and the

Notification we configured.This is demonstrated with the following code:

              private static final int NOTIFY_1 = 0x1001;

              // ...

              notifier.notify(NOTIFY_1, notify);

 

The identifier matches up a Notification with any previous Notification instances of

that type.When the identifiers match, the old Notification is updated instead of creating

a new one.You might have a Notification that some file is being downloaded.You could

update the Notification when the download is complete, instead of filling the

Notification queue with a separate Notification, which quickly becomes obsolete.

This Notification identifier only needs to be unique within your application.

The notification displays as an icon and ticker text showing up on the status bar.

 

 

Updating Notifications

You don't want your application's notifications piling up in the notification bar.Therefore,

you might want to reuse or update notifications to keep the notification list manageable.

 

For example, there is no reason to keep a notification informing the user that the application

is downloading File X when you now want to send another notification saying File

X has finished downloading. Instead, you can simply update the first notification with new

information.

 

When the notification identifiers match, the old notification is updated.When a notification

with matching identifier is posted, the ticker text does not draw a second time.To

show the user that something has changed, you can use a counter.The value of the

number member variable of the Notification object tracks and displays this. For instance,

we can set it to the number 4, as shown here:

              notify.number = 4;

 

This is displayed to the user as a small number over the icon.This is only displayed in the

status bar and not in the expanded status bar, although an application could update the text to also display this information.

 

 

Clearing Notifications

When a user clicks on the notification, the Intent assigned is triggered.At some point

after this, the application might want to clear the notification from the system notifications

queue.This is done through a call to the cancel() method of the

 

NotificationManager object. For instance, the notification we created earlier could be

canceled with the following call:

              notifier.cancel(NOTIFY_1);

 

This cancels the notification that has the same identifier.However, if the application doesn't

care what the user does after clicking on the notification, there is an easier way to cancel

notifications. Simply set a flag to do so, as shown here:

              notify.flags |= Notification.FLAG_AUTO_CANCEL;

 

Setting the Notification.FLAG_AUTO_CANCEL flag causes notifications to be canceled

when the user clicks on them.This is convenient and easy for the application when just

launching the Intent is good enough.

 

The Notification object is a little different from other Android objects you might

have encountered. Most of the interaction with it is through direct access to its public

variables instead of through helper methods.This is useful for a background application or

service, The Notification object can be kept around and only the values that need to be

changed can be modified.After any change, the Notification needs to be posted again by

calling the notify() method.

 

 

Vibrating the Phone

Vibration is a great way to enable notifications to catch the attention of a user in noisy

environments or alert the user when visible and audible alerts are not appropriate (though

a vibrating phone is often noisy on a hard desktop surface).Android notifications give a

fine level of control over how vibration is performed. However, before the application can

use vibration with a notification, an explicit permission is needed.The following XML

within your application's AndroidManifest.xml file is required to use vibration:

              <uses-permission

                            android:name="android.permission.VIBRATE" />

 

Without this permission, the vibrate functionality will not work nor will there be any

error.With this permission enabled, the application is free to vibrate the phone however it

wants.This is accomplished by describing the vibrate member variable, which determines

the vibration pattern.An array of long values describes the vibration duration.

Thus, the following line of code enabled a simple vibration pattern that occurs whenever

the notification is triggered:

              notify.vibrate = new long[] {0, 200, 200, 600, 600};

 

This vibration pattern vibrates for 200 milliseconds and then stops vibrating for 200

milliseconds. After that, it vibrates for 600 milliseconds and then stops for that long.To

repeat the Notification alert, a notification flag can be set so it doesn't stop until the user

clears the notification.

              notify.flags |= Notification.FLAG_INSISTENT;

 

An application can use different patterns of vibrations to alert the user to different types of

events or even present counts. For instance, think about a grandfather clock with which

you can deduce the time based on the tones that are played.

 

 

Blinking the Lights

Blinking lights are a great way to pass information silently to the user when other forms

of alert are not appropriate.The Android SDK provides reasonable control over a multicolored

indicator light, when such a light is available on the device. Users might recognize

this light as a service indicator or battery level warning.An application can take advantage

of this light as well, by changing the blinking rate or color of the light.

 

You must set a flag on the Notification object to use the indicator light.Then, the color

of the light must be set and information about how it should blink.The following block

of code configures the indicator light to shine green and blink at rate of 1 second on and

1 second off:

              notify.flags |= Notification.FLAG_SHOW_LIGHTS;

              notify.ledARGB = Color.GREEN;

              notify.ledOnMS = 1000;

              notify.ledOffMS = 1000;

 

Although you can set arbitrary color values, a typical physical implementation of the

indicator light has three small LEDs in red, green, and blue.Although the colors blend

reasonably well, they won't be as accurate as the colors on the screen. For instance, on the

T-Mobile G1, the color white looks a tad pink.

 

An application can use different colors and different blinking rates to indicate different

information to the user. For instance, the more times an event occurs, the more urgent the

indicator light could be.The following block of code shows changing the light based on

the number of notifications that have been triggered:

              notify.number++;

              notify.flags |= Notification.FLAG_SHOW_LIGHTS;

              if (notify.number < 2) {

                            notify.ledARGB = Color.GREEN;

                            notify.ledOnMS = 1000;

                            notify.ledOffMS = 1000;

              } else if (notify.number < 3) {

                            notify.ledARGB = Color.BLUE;

                            notify.ledOnMS = 750;

                            notify.ledOffMS = 750;

              } else if (notify.number < 4) {

                            notify.ledARGB = Color.WHITE;

                            notify.ledOnMS = 500;

                            notify.ledOffMS = 500;

              } else {

                            notify.ledARGB = Color.RED;

                            notify.ledOnMS = 50;

                            notify.ledOffMS = 50;

              }

 

The blinking light continues until the Notification is cleared by the user.The use of the

Notification.FLAG_INSISTENT flag does not affect this as it does vibration effects.

Color and blinking rates could also be used to indicate other information. For instance,

temperature from a weather service could be indicated with red and blue plus blink rate.

Use of such colors for passive data indication can be useful even when other forms would

work. It is far less intrusive than annoying, loud ringers or harsh, vibrating phone noises.

 

 

Making Noise

Sometimes, the handset has to make noise to get the user's attention. Luckily, the Android

SDK provides a means for this using the Notification object. Begin by configuring the

audio stream type to use when playing a sound. Generally, the most useful stream type is

STREAM_NOTIFICATION.You can configure the audio stream type on your notification as

follows:

              notify.audioStreamType = AudioManager.STREAM_NOTIFICATION;

 

Now, assign a valid Uri object to the sound member variable and that sound plays when

the notification is triggered.The following code demonstrates how to play a sound that is

included as a project resource:

              notify.sound = Uri.parse(

                                          "android.resource://com.androidbook.simplenotifications/" +

                                          R.raw.fallbackring);

 

By default, the audio file is played once.As with the vibration, the

Notification.FLAG_INSISTENT flag can be used to repeat incessantly until the user clears

the notification. No specific permissions are needed for this form of notification.

 

 

Customizing the Notification

Although the default notification behavior in the expanded status bar tray is sufficient for

most purposes, developers can customize how notifications are displayed if they so choose.

To do so, developers can use the RemoteViews object to customize the look and feel of a

notification.

 

The following code demonstrates how to create a RemoteViews object and assign custom

text to it:

              RemoteViews remote =

              new RemoteViews(getPackageName(), R.layout.remote);

              remote.setTextViewText(R.id.text1, "Big text here!");

              remote.setTextViewText(R.id.text2, "Red text down here!");

              notify.contentView = remote;

 

To better understand this, here is the layout file remote.xml referenced by the preceding

code:

              <LinearLayout

                            xmlns:android="http://schemas.android.com/apk/res/android"

                            android:orientation="vertical"

                            android:layout_width="fill_parent"

                            android:layout_height="fill_parent">

 

                            <TextView

                                          android:id="@+id/text1"

                                          android:layout_width="fill_parent"

                                          android:layout_height="wrap_content"

                                          android:textSize="31dp"

                                          android:textColor="#000" />

 

                            <TextView

                                          android:id="@+id/text2"

                                          android:layout_width="fill_parent"

                                          android:layout_height="wrap_content"

                                          android:textSize="18dp"

                                          android:textColor="#f00" />

              </LinearLayout>

 

This particular example is similar to the default notification but does not contain an icon.

The setLatestEventInfo() method is normally used to assign the text to the default

layout. In this example,we use our custom layout instead.The Intent still needs to be

assigned, though, as follows:

 

              Intent toLaunch = new Intent

                            (SimpleNotificationsActivity.this, SimpleNotificationsActivity.class);

              PendingIntent intentBack = PendingIntent.getActivity

                            (SimpleNotificationsActivity.this, 0, toLaunch, 0);

              notify.contentIntent = intentBack;

              notifier.notify(NOTIFY_5, notify);

 

Using a custom notification layout can provide better control over the information on

the expanded status bar.Additionally, it can help differentiate your application's notifications

from other applications by providing a themed or branded appearance.

 

 

Designing Useful Notifications

As you can see, the notification capabilities on the Android platform are quite robust?so

robust that it is easy to overdo it and make your application tiresome for the user. Here

are some tips for designing useful notifications:

Only use notifications when your application is not in the foreground.When in the

foreground, use Toast or Dialog controls.

Allow the user to determine what types (text, lights, sound, vibration) and frequency

of notifications she will receive, as well as what events to trigger notifications

for.

Whenever possible, update and reuse an existing notification instead of creating a

new one.

Clear notifications regularly so as not to overwhelm the user with dated information.

When in doubt, generate "polite" notifications (read: quiet).

Make sure your notifications contain useful information in the ticker, title, and

body text fields and launch sensible intents.

 

The notification framework is lightweight yet powerful. However, some applications such

as alarm clocks or stock market monitors might also need to implement their own alert

windows above and beyond the notification framework provided. In this case, they may

use a background service and launch full Activity windows upon certain events. In

Android 2.0 and later, developers can use the WindowManager.LayoutParams class to

enable activity windows to display, even when the screen is locked with a keyguard.

 

0 件のコメント:

コメントを投稿