13.5. 发送通知
13.5.发送通知
到这里再体验一个系统服务——那就是Notification服务。前面我们花了大功夫让UpdaterService在后台运行,并定期抓取消息的最新更新。但是如果用户压根注意不到它,那么这些工作还有什么意义?Android的标准解决方案就是,在屏幕顶部的通知栏弹出一个通知。而实现这一功能,需要用到Notification服务。
收到新消息,由UpdaterService首先得知,因此我们把通知的功能加入到UpdaterService类里:先获取Notification服务的引用,创建一个Notification对象,然后将收到消息的相关信息作为通知交给它。而Notification对象本身带有一个PendingIntent,当用户点击通知的时候,可以将界面转到Timeline界面。
例 13.15. UpdaterService.java,利用Notification服务
package com.marakana.yamba8;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
public class UpdaterService extends IntentService {
private static final String TAG = "UpdaterService";
public static final String NEW_STATUS_INTENT = "com.marakana.yamba.NEW_STATUS";
public static final String NEW_STATUS_EXTRA_COUNT = "NEW_STATUS_EXTRA_COUNT";
public static final String RECEIVE_TIMELINE_NOTIFICATIONS = "com.marakana.yamba.RECEIVE_TIMELINE_NOTIFICATIONS";
private NotificationManager notificationManager; //
private Notification notification; //
public UpdaterService() {
super(TAG);
Log.d(TAG, "UpdaterService constructed");
}
@Override
protected void onHandleIntent(Intent inIntent) {
Intent intent;
this.notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); //
this.notification = new Notification(android.R.drawable.stat_notify_chat,
"", 0); //
Log.d(TAG, "onHandleIntent'ing");
YambaApplication yamba = (YambaApplication) getApplication();
int newUpdates = yamba.fetchStatusUpdates();
if (newUpdates > 0) {
Log.d(TAG, "We have a new status");
intent = new Intent(NEW_STATUS_INTENT);
intent.putExtra(NEW_STATUS_EXTRA_COUNT, newUpdates);
sendBroadcast(intent, RECEIVE_TIMELINE_NOTIFICATIONS);
sendTimelineNotification(newUpdates); //
}
}
/**
* Creates a notification in the notification bar telling user there are new
* messages
*
* @param timelineUpdateCount
* Number of new statuses
*/
private void sendTimelineNotification(int timelineUpdateCount) {
Log.d(TAG, "sendTimelineNotification'ing");
PendingIntent pendingIntent = PendingIntent.getActivity(this, -1,
new Intent(this, TimelineActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT); //
this.notification.when = System.currentTimeMillis(); //
this.notification.flags |= Notification.FLAG_AUTO_CANCEL; //
CharSequence notificationTitle = this
.getText(R.string.msgNotificationTitle); //
CharSequence notificationSummary = this.getString(
R.string.msgNotificationMessage, timelineUpdateCount);
this.notification.setLatestEventInfo(this, notificationTitle,
notificationSummary, pendingIntent); //
this.notificationManager.notify(0, this.notification);
Log.d(TAG, "sendTimelineNotificationed");
}
}
- 指向NotificationManager的私有类成员,也就通过它来访问Notification系统服务。
- 创建一个Notification对象供类成员访问,每得到新消息需要发送通知时就更新它。
- 调用getSystemService()获取Notification服务。
- 创建Notification对象,在稍后使用。在这里先给它指明一个图标,至于通知的文本和时间戳(timestamp)则暂时留空。
- 私有方法sendTimelineNotification(),在得到新消息时调用它发送通知。
- 当用户收到通知并点击通知条目时,切换到Timeline界面,这个PendingIntent也随之销毁。
- 更新Notification对象的相关信息。这里是最新消息的timestamp。
- 要求NotificationManager在用户点击时关闭这项通知,届时通知栏将不再显示这项通知。
- 为Notification对象提供标题(title)与简介(summary),都是取自string.xml中的字符串。留意R.string.msgNotificationMessage里面留了一个参数,表示新消息的数目,因此我们可以使用String.format()。
- 最后,要求NotificationManager发送这条通知。在这里,我们不需要通知的ID,因此留0。ID是引用Notification对象的标识符,通常用来关闭一个通知。