创建状态栏通知

状态栏通知会向系统状态栏添加一个图标(还可以附有文本消息)以及一条“通知”窗口内的可扩展消息。当用户选择了该可扩展消息,Android发出一个有通知定义的Intent(通常来启动一个活动)。也可以设置通知来以声音、振动和设备闪光来提醒用户。

状态栏通知应当被用于任何后台服务需要提示用户发生了事件并要求回应的情况。后台服务不应自己启动活动来接收用户交互操作。它应当创建一个状态栏通知,在用户选择该通知时启动一个活动。

下面的截图展示了一个左侧有通知图标的状态栏。

下一张截图展示了“通知”窗口中扩展的通知消息。将状态栏下拉可展开通知窗口(或从主页面选项菜单中选择“通知”)。

基本内容

活动或是服务可以初始化一个状态栏通知。由于一个活动只有在其状态是活动的且处于焦点时才能执行行动,所以应当通过服务来创建状态栏通知。这样,通知就能从后台创建,即使用户在使用另一个程序或是设备处于休眠状态。要创建通知,必须使用两个类:Notification和NotificationManager。

使用Notification类的一个实例来定义状态栏通知的属性,例如状态栏图标,扩展消息,或要播放的音效等更多内容。NotificationManager是一个Android系统服务,它执行并管理所有Notification。不必实例化NotificationManager。为了传递Notification,必须通过getSystemService()获取NotificationManager的一个引用,之后再希望通知用户时,使用notify()将其传递给自己的Notification对象。

要创建一个状态栏通知:

1.获取NotificationManager的一个引用

2.实例化Notification:

3.定义Notification的扩展消息和Intent:

4.将Notification传递给NotificationManager:

这样之后,用户将收到通知。

管理通知

一个Notification对象定义显示于状态栏和通知窗口的通知消息的具体细节以及其他提示设置,例如声音或是灯光闪烁。必须通过getSystemService()方法检索一个指向它的引用。例如:

在希望发送状态栏通知时,需要用notify(int, Notification)来传递Notification对象至NotificationManager。第一个参数是Notification的唯一ID,第二个是Notification对象。ID唯一识别了程序中的Notification。如果需要更新Notification或(程序管理多个不同Notification时)在用户由Notification中定义的Intent返回程序时选择正确的行动,这将会是很必要的。

要在用户从通知窗口中选择状态栏通知的同时清除它的话,就向Notification对象添加”FLAG_AUTO_CANCEL”旗标。也可以手动地通过向cancel(int)传递通知ID来清除,或使用cancelAll()来清除全部通知。

创建通知

一个Notification对象定义了显示在状态栏和通知窗口的通知消息的细节,以及其他提示的设置,例如声音和灯光闪烁。

一个状态栏通知需要以下所有内容:

  • 一个状态栏的图标
  • 一个标题和扩展视图中的扩展消息(除非另外自定义了一个的扩展视图)
  • 一个PendingIntent,以供在通知被选中时放出

状态栏通知的可选设置则包括:

  • 状态栏的ticker-text消息(注:暂时还没有决定怎么翻译这个ticker-text比较好)
  • 提示音
  • 振动设置
  • LED灯设置

新建一个Notification的基本内容包括构造函数Notification(int, CharSequence, long)和setLatestEventInfo(Context, CharSequence, CharSequence, PendingIntent)方法。它们定义了一个Notification所需的所有设置。下面的片段展示了一种基本的通知创建方式:

更新通知

在程序中的事件持续发展的过程中可以不断更新状态栏通知中的信息。例如,在前一条短信被阅读前又收到新的一条时,短消息程序会更新现有通知,显示收到的未读短信的总数。这一更新通知的做法要比向NotificationManager添加新的通知更好,因为它避免了使通知窗口变得杂乱。

由于每一个通知都有NotificationManager通过一个整型ID唯一定义,因此可以通过以新值调用setLatestEventInfo()来修改通知,改变Notification的一些域的值,之后再次调用notify()。

可以通过对象成员域来修改每一种属性(除了Context和扩展消息标题及文本)。应当始终在通过新值调用setLatestEventInfo()更新通知时修改contentTitlecontentText的文本消息。之后调用notify()来更新通知。(当然,如果创建了自定义扩展视图,那更新这些标题和文本的值就没有效果了。)

添加声音

可以使用(用户所定义的)默认消息提示音或是程序指定的声音来提示用户。

要使用用户默认提示音,在defaults域中添加“DEFAULT_SOUND”:

要在程序中使用不同的提示音,需要传入一个Uri引用至sound域。下面的例子使用了一个保存于设备SD卡中的已知音频文件:

接下来的例子中,音频文件是从内部的MediaStore的ContentProvider中选择的:

在本例中,媒体文件的确切ID(”6″)是已知的,附加于内容Uri之上。如果不知道确切的ID,就必须使用ContentResolver来请求所有MediaStore内可用的媒体。参见内容提供者文档中关于使用ContentResolver的更多信息。

如果希望声音在用户响应通知或通知被取消前不断持续,就在flags域中添加“FLAG_INSISTENT”。

注意:如果defaults域包含了“DEFAULT_SOUND”,那么默认声音将会覆盖其他所有定义过的sound域。

添加振动

可以使用默认振动模式或是程序自定义的振动模式来提醒用户。

要使用默认模式,在defaults域中添加“DEFAULT_VIBRATE”:

要定义属于自己的振动模式,需向vibrate域传递一组long型数组值:

long型数组定义了震动有无的时长间隔(以毫秒计)。第一个值是在开始之前等待的时间(无震动),第二个值是首次震动的长度,第三个值是之后的暂停时长,依此类推。振动模式可以为任意长度,不过不能设置循环。

注意:如果defaults域包含了“DEFAULT_VIBRATE”,那么默认振动将覆盖所有在vibrate域中定义的震动。

添加灯光闪烁

要使用LED灯光闪烁来提醒用户,可以用默认灯光模式(如果可用),或自定义灯光模式及色彩。

要使用默认灯光设置,在defaults域中添加“DEFAULT_LIGHTS”:

要自定义模式和色彩,需要为ledARGB域(色彩),ledOffMS域(LED关闭时长,单位毫秒)和ledOnMS域(LED开启时长,单位毫秒)设定值,并在flags域添加“FLAG_SHOW_LIGHTS”:

在这个例子中,绿灯将反复闪烁,亮300毫秒,暗1秒。设备的LED并不支持光谱中所有的色彩,每一种设备支持的色彩也有不同,硬件会尽可能提供最佳效果。绿色是最常用的通知色彩。

更多特性

可以通过Notification域和旗标向通知添加更多特性。包括以下有用的特性:

“FLAG_AUTO_CANCEL”

旗标将其加入flags域以在通知被从通知窗口中选择时自动取消

“FLAG_INSISTENT”

旗标将其加入flags域以重复音频播放直至用户回应

“FLAG_ONGOING_EVENT”

旗标将其加入flags域以将通知分组于通知窗口的“正在进行”标题之下。这表示程序正在运行——它的进程仍在后台运行,尽管程序本身不可见(例如音乐和通话)

“FLAG_NO_CLEAR”

旗标将其加入flags域以表明通知不应当被“清除通知”按钮清除。这在程序正在运行时很有用。

number

这个值显示了当前被通知所表示的事件数。正确的数字会在状态栏图标顶部显示。如果要用这个域,那就必须在通知被创建时从“1”开始计数。(如果在一次更新时将这个值由零改为了比零大的任何数,这个数字就不会被显示。)

iconLevel

这个值显示了当前用于通知图标的LevelListDrawable等级。配合在LevelListDrawable中定义的drawable,可以通过改变这个值使状态栏中的图标呈现动画效果。参见LevelListDrawable以获取更多信息。

参见Notification类参考资料以获取关于添加特性来自定义程序的更多信息。

创建自定义扩展视图

默认情况下用于通知窗口的扩展视图包括基本的标题和文本消息。这些是由setLatestEventInfo()方法的contentTitlecontentText参数所定义。然而,也可以使用RemotiViews来自定义扩展视图的布局。下面的屏幕截图展示了一个以线性布局使用ImageView和TextView的自定义扩展视图。

要定义扩展消息自有的布局,需要实例化RemoteViews对象并将其传递给Notification的contentView域。还要将PendingIntent传递给contentIntent域。

可以通过一个范例来更好的理解如何创建一个自定义扩展视图:

1.创建扩展视图的XML布局。例如,创建一个名为custom_notification_leyout.xml的布局文件并像这样编写:

该布局将被用于扩展视图,不过ImageView和TextView的内容仍需要由程序来定义。RemoteViews提供了一些用以定义这些内容的便利方法…

2.在程序代码中,使用了RemoveViews方法来定义了图片和文本。之后将RemoteViews对象传递至Notification的contentView域,就像这样:

如上所示,将程序的package名和布局资源ID传递给RemoteViews的构造函数。之后,通过setImageViewResourse()和setTextViewText()来定义ImageView和TextView的内容。两者都需要传递希望使用的View对象的正确的引用ID以及其值。最后RemoteViews对象被传递到了Notification的contentView域。

3.因为在使用自定义视图时不需要使用setLatestEventInfo()方法,所以必须在contentIntent域中定义Notification所使用的Intent,如下所示:

4.现在通知就可以像往常一样被发送了:

RemoteViews类还包括可以用来在通知的扩展视图中轻松添加Chronometer(计时器)或是ProgressBar(进度条)的方法。关于通过RemoteViews来创建自定义布局更多信息,请参考RemoteViews类的参考资料。

注意:在创建自定义扩展视图时,必须非常小心以确保自定义布局在不同设备方向(orientation,即横屏或是竖屏)和分辨率下都能正常工作。尽管这个建议对于Android上创建的所有View布局来说都是值得注意的,但在这一部分里尤为重要,因为布局所受的限制非常严格。所以不要将自定义布局设计的过于复杂,此外应当在多种不同情况下作测试。

返回通知用户

本作品采用知识共享 署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。

发表评论

电子邮件地址不会被公开。 必填项已用*标注