当前位置: 首页 > news >正文

android 中 Notification 关于状态栏的一些操作


状态栏(status bar)通知将一个图标填加到系统的状态栏中(包含一条可选的提示文本信息),并将一条展开信息添加到通知窗口中。当用户选中展开信息时,Android将执行一个此通知已定义的意图Intent(通常用于弹出一个Activity)。你还可以对通知进行配置,用设备提供的声音、振动、闪光来提醒用户。

当后台服务(Service)需要对某个事件发出提醒并且需要用户响应时,状态栏通知就能发挥作用了。后台服务从来不会启动Activity来接收用户的交互,取而代之的是应该创建一个状态栏通知,在用户点选后再由通知来启动Activity。

以下截图展示了一个左侧带有通知图标的状态栏:

下图展示了“Notifications”窗口内的通知展开信息。用户可通过下拉状态栏(或在Home菜单里选中通知)来显示这个通知窗口。

想了解更多关于通知的设计,可以参考Android Design的通知指南。

基本内容

Activity或者Service都能初始化一个状态栏通知。可因为Activity只有在活动状态并获得焦点时才能执行操作,所以还是建议用Service来创建状态栏通知。这样,即使用户正在使用其他程序或者设备已经休眠时,仍然可以从后台创建通知。要创建一个通知,须用到两个类:Notification类和NotificationManager类。

用Notification类的一个实例来定义状态栏通知的属性,比如图标、展开信息,以及播放声音等附属设置。NotificationManager是一个Android系统服务,用于管理和运行所有通知。NotificationManager不能被实例化,为了把Notification传给它,你可以用getSystemService()方法获取一个NotificationManager的引用。在需要通知用户时再调用notify()方法将Notification对象传给它。

要创建一个状态栏通知:

1. 获取NotificationManager的引用:

String ns =Context.NOTIFICATION_SERVICE; 
NotificationManager mNotificationManager =(NotificationManager) getSystemService(ns);

2. 实例化Notification:

int icon = R.drawable.notification_icon; 
CharSequence tickerText ="Hello"; 
longwhen=System.currentTimeMillis(); 
Notification notification =newNotification(icon, tickerText,when);

3. 指定通知的展开信息和Intent:

Context context = getApplicationContext(); 
CharSequence contentTitle ="My notification"; 
CharSequence contentText ="Hello World!"; 
Intent notificationIntent =newIntent(this,MyClass.class); 
PendingIntent contentIntent =PendingIntent.getActivity(this,0, notificationIntent,0); 
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);]

4. 将Notification对象传给NotificationManager:

privatestaticfinalint HELLO_ID =1;  
mNotificationManager.notify(HELLO_ID, notification);

好了,现在用户已经能看到通知了。

响应通知(待翻译)

管理通知

系统服务 NotificationManager 管理着所有的通知,只能通过 getSystemService() 方法来获取它的引用。例如:

String ns =Context.NOTIFICATION_SERVICE; 
NotificationManager mNotificationManager =(NotificationManager) getSystemService(ns);

如果想要发送状态栏通知,通过 notify(int, Notification) 传递 Notification 对象给 NotificationManager 即可。第一个参数是 Notification 的唯一ID,第二个参数是Notification 对象。ID在整个应用程序范围内唯一标识 Notification 。Notification 需要更新;应用程序可能管理着多种不同的通知,在用户通过各自定义的Intent返回应用程序时必须能选择正确的动作执行之,因此上述参数是必需的。

要实现用户从通知窗口内点选后自动清除状态栏通知,请在 Notification 对象中加入“FLAG_AUTO_CANCEL”标志。也可以传入通知ID用cancel(int)手动清除,或者用cancelAll()清除所有你创建的通知。

创建通知

Notification对象定义了通知消息显示在状态栏和通知窗口上的细节内容,以及其他提醒设置(比如:声音、闪光等)。

状态栏通知必须包括以下内容:

  • 状态栏图标
  • 展开窗口view的标题和展开信息(除非用了自定义展开view)
  • PendingIntent,当通知被点选时执行

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

  • 状态栏提示信息
  • 提醒声音
  • 震动设置
  • LED灯闪光设置

Notification的基础库里包含了构造方法Notification(int, CharSequence, long)和setLatestEventInfo(Context, CharSequence, CharSequence, PendingIntent)方法。这已经可以定义Notification的所有设置。以下代码段演示了对通知基本的设置:

int icon = R.drawable.notification_icon;       
CharSequence tickerText ="Hello";              
longwhen=System.currentTimeMillis();         
Context context = getApplicationContext();      
CharSequence contentTitle ="My notification"; 
CharSequence contentText ="Hello World!";      

Intent notificationIntent =newIntent(this,MyClass.class); 
PendingIntent contentIntent =PendingIntent.getActivity(this,0, notificationIntent,0); 

// the next two lines initialize the Notification, using the configurations above 
Notification notification =newNotification(icon, tickerText,when); 
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

更新通知

应用程序可以在事件正在进行时更新状态栏通知。比如,前一条短信还未读,可又来了一条新短信,短信程序为了正确显示未读短信的总数,可以更新已有的通知。此时,更新原有通知要比向 NotificationManager 新增一条通知更合理些,因为避免了通知窗口的显示混乱。

因为 NotificationManager 对每个通知都用一个整数ID进行了唯一标识,新的通知内容可以用 setLatestEventInfo() 方法方便地进行修改,然后再次调用notify()显示出来。

除了Context、展开信息的标题和文本外,可以利用对象的成员值修改每个属性。要修改通知的文本信息,只能对 contentTitle 和 contentText 参数赋新值并调用 setLatestEventInfo() ,然后再调用notify()方法来更新通知。(当然,如果已经创建了自定义扩展view,那么标题和文本的修改就无效了)。

添加声音

可以用缺省提示音(由用户指定)或者程序指定声音来提醒用户。

要使用用户缺省提示音,给defaults属性添加“DEFAULT_SOUND”:

notification.defaults |=Notification.DEFAULT_SOUND;

要使用应用程序指定的声音,则传递一个Uri引用给sound属性。以下例子使用已保存在设备SD卡上的音频文件作为提示音:

notification.sound =Uri.parse("file:///sdcard/notification/ringer.mp3");

在下面的例子里,音频文件从内部MediaStore类的ContentProvider中获取:

notification.sound =Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI,"6");

这时,已知有资源ID为6的媒体文件,并且已添加到Uri内容中。如果不知道确切的ID,则必须先用 ContentResolver 查询 MediaStore 中所有可用的资源。关于使用 ContentResolver的详细信息请参阅Content Providers文档。

如果期望在用户响应通知或取消通知前,声音一直持续循环播放,可以把“FLAG_INSISTENT”加入flags属性中。

注意:如果defaults属性包含了“DEFAULT_SOUND”,则缺省提示音将覆盖sound属性里指定的声音。

添加振动

可以用缺省震动模式或程序指定的振动模式来提醒用户。

要用缺省震动模式,给属性defaults添加“DEFAULT_VIBRATE”即可:

notification.defaults |=Notification.DEFAULT_VIBRATE;

要自定义震动模式,须给vibrate属性传递一个long类型的数组:

long[] vibrate ={0,100,200,300}; 
notification.vibrate = vibrate;

长整型数组定义了震动开和关交替的时间(毫秒)。第一个数是开始振动前的等待时间(震动关闭),第二个数是第一次开启振动的持续时间,第三个数是下一次关闭时间,如此类推。振动模式的持续时间没有限制,但不能设置为重复振动。

注意:如果defaults属性包含了“DEFAULT_VIBRATE”,则缺省的震动模式将会覆盖vibrate属性里指定的模式。

添加灯光闪烁

要想用LED闪光来提醒用户,可以执行缺省闪光模式(如果可用的话),也可以自定义闪光的颜色和模式。

要使用缺省的闪光设置,给属性defaults添加“DEFAULT_LIGHTS”即可:

notification.defaults |=Notification.DEFAULT_LIGHTS;

要自定义颜色和模式,则须指定ledARGB属性(指颜色)、ledOffMS属性(闪光关闭毫秒数)、ledOnMS属性(闪光开启毫秒数),并在“flags”属性里加入“FLAG_SHOW_LIGHTS”:

notification.ledARGB =0xff00ff00; 
notification.ledOnMS =300; 
notification.ledOffMS =1000; 
notification.flags |=Notification.FLAG_SHOW_LIGHTS;

上例实现了绿色光闪烁300毫秒间歇1秒的闪光。每个设备的LED灯不可能支持所有颜色的发光,不同的设备所能支持的颜色也各不相同,因此硬件将按照最接近的颜色来发光。绿色是最常见的提醒色。

更多特性

利用Notification的属性和标志位,可以给通知添加更多的特性。

下面列出了其中一些常用的特性:

  • “FLAG_AUTO_CANCEL”标志 在flags属性中增加此标志,则在通知窗口点选后能自动取消通知。
  • “FLAG_INSISTENT”标志 在flags属性中增加此标志,则在用户响应前一直循环播放声音。
  • “FLAG_ONGOING_EVENT”标志 在flags属性中增加此标志,则将通知放入通知窗口的“正在运行”(Ongoing)组中。表示应用程序正在运行——进程仍在后台运行,即使应用程序不可见(比如播放音乐或接听电话)。
  • “FLAG_NO_CLEAR”标志 在flags属性中增加此标志,表示通知不允许被“清除通知”按钮清除。这在期望通知保持运行时特别有用。
  • number属性 表示通知所代表的事件数量。此数字显示在状态栏图标上。要利用此属性, 必须在第一次创建通知时设为1。(如果只是在更新通知时才把此值从0改成任意大于0的数,则数字不会显示出来。)
  • iconLevel属性 表示通知图标当前的LevelListDrawable等级。通过改变这个值,可以在状态栏中显示图标的动画,这个值与 LevelListDrawable 中 drawable 的定义相关。详情请参阅 LevelListDrawable。

程序能自定义更多特性,详情请参阅Notification。

创建自定义通知

默认情况下,通知窗口中的展开视图(view)包括基本的标题和文本信息。这是由 setLatestEventInfo() 的 contentTitle 和 contentText 参数指定的。不过仍可以用 RemoteViews来自定义一个展开视图的布局。右侧的截图就展示了一个自定义展开视图的例子,其中用到了LinearLayout 布局中的ImageView和TextView。

要自定义展开信息的布局,需要实例化一个RemoteViews对象,并将它传递给 Notification 的contentView 属性,同时把 PendingIntent 传给 contentIntent 属性。

通过例子是对创建自定义展开视图最好的理解方式:

1. 为展开视图新建XML布局,建立一个名为custom_notification_layout.xml的布局文件,内容如下:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" 
              android:orientation="horizontal" 
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent" 
              android:padding="3dp" 
              > 
    <ImageViewandroid:id="@+id/image" 
              android:layout_width="wrap_content" 
              android:layout_height="fill_parent" 
              android:layout_marginRight="10dp" 
              /> 
    <TextViewandroid:id="@+id/text" 
              android:layout_width="wrap_content" 
              android:layout_height="fill_parent" 
              android:textColor="#000" 
              /> 
</LinearLayout>

此布局用于展开视图,但ImageView和TextView的内容还需要由应用程序来定义。RemoteViews提供了一些方便的方法来定义这些内容。

2. 在应用程序代码里,用RemoteViews的方法来定义图片和文字。然后把RemoteViews对象传给Notification的contentView属性,如下所示:

RemoteViews contentView =newRemoteViews(getPackageName(), R.layout.custom_notification_layout); 
contentView.setImageViewResource(R.id.image, R.drawable.notification_image); 
contentView.setTextViewText(R.id.text,"Hello, this message is in a custom expanded view"); 
notification.contentView = contentView;

如上:先把程序package名和布局资源ID传给RemoteViews的构造方法。然后用setImageViewResource()和setTextViewText()定义ImageView和TextView的内容,分别把View对象的资源ID、所赋的内容作为参数传入。最后,把RemoteViews对象传给Notification的contentView属性。

3. 由于自定义视图不需要执行setLatestEventInfo() 方法,因此必须用contentIntent属性来定义一个通知所要执行的意图Intent ,如下:

Intent notificationIntent =newIntent(this,MyClass.class); 
PendingIntent contentIntent =PendingIntent.getActivity(this,0, notificationIntent,0); 
notification.contentIntent = contentIntent;

4. 现在通知可以如常发送了:

mNotificationManager.notify(CUSTOM_VIEW_ID, notification);

RemoteViews类还包含了一些方法,便于在通知的展开视图里增加 Chronometer 或 ProgressBar 。关于用RemoteViews创建自定义布局的详细信息,请参阅RemoteViews类的参考文档。


转载:http://wiki.heyitao.com/program/android/guide/topics-ui-notifiers-notifications

注意:当建立一个自定义展开视图时,必须特别小心,保证自定义的布局能正常工作在不同的设备方向和分辨率下。这个建议对于所有在Android上创建的View布局都是适用的,但在这种情况下尤为重要,因为布局实际可用的屏幕区域非常有限。不要把自定义布局设计得过于复杂,并且一定要在各种环境配置下进行测试。

相关文章:

  • SQL SERVER 2012 使用订阅发布同步数据库(一)
  • java.net.MalformedURLException: no protocol: 解决方式
  • css中border-width 属性
  • Erlang改变当前工作路径
  • SQL SERVER 2012 使用订阅发布同步数据库(二)
  • 小智慧48
  • 小智慧49
  • Linux的多任务编程-线程
  • 黑马程序员_String类
  • 洪水预报系统的读书笔记
  • android 关于闹钟
  • CSS中首字母大写怎么实现?
  • android环境下解决java.io.IOException: Malformed ipv6异常的方法
  • Scatter“秒传”的速度秒杀了云存储
  • 腾讯移动游戏平台发布了《天天酷跑》游戏
  • 网络传输文件的问题
  • [译]前端离线指南(上)
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • isset在php5.6-和php7.0+的一些差异
  • Javascript Math对象和Date对象常用方法详解
  • JS 面试题总结
  • Linux CTF 逆向入门
  • Linux下的乱码问题
  • node-glob通配符
  • Shell编程
  • Spring框架之我见(三)——IOC、AOP
  • Vue组件定义
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 仿天猫超市收藏抛物线动画工具库
  • 给第三方使用接口的 URL 签名实现
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • raise 与 raise ... from 的区别
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • !$boo在php中什么意思,php前戏
  • #QT(串口助手-界面)
  • (04)odoo视图操作
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (6)设计一个TimeMap
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (SpringBoot)第七章:SpringBoot日志文件
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (二)斐波那契Fabonacci函数
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (蓝桥杯每日一题)love
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .bat批处理出现中文乱码的情况
  • .NET 8.0 发布到 IIS
  • .NET Core 2.1路线图