13.5. 发送通知

优质
小牛编辑
130浏览
2023-12-01

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");

}

}

  1. 指向NotificationManager的私有类成员,也就通过它来访问Notification系统服务。
  2. 创建一个Notification对象供类成员访问,每得到新消息需要发送通知时就更新它。
  3. 调用getSystemService()获取Notification服务。
  4. 创建Notification对象,在稍后使用。在这里先给它指明一个图标,至于通知的文本和时间戳(timestamp)则暂时留空。
  5. 私有方法sendTimelineNotification(),在得到新消息时调用它发送通知。
  6. 当用户收到通知并点击通知条目时,切换到Timeline界面,这个PendingIntent也随之销毁。
  7. 更新Notification对象的相关信息。这里是最新消息的timestamp。
  8. 要求NotificationManager在用户点击时关闭这项通知,届时通知栏将不再显示这项通知。
  9. 为Notification对象提供标题(title)与简介(summary),都是取自string.xml中的字符串。留意R.string.msgNotificationMessage里面留了一个参数,表示新消息的数目,因此我们可以使用String.format()。
  10. 最后,要求NotificationManager发送这条通知。在这里,我们不需要通知的ID,因此留0。ID是引用Notification对象的标识符,通常用来关闭一个通知。