某个程序希望像用户发出一些提示信息,而该应用程序又不在前台运行时候,可以借助通知来实现这样的功能。效果就是在下拉状态栏后看到的那些:某某明星又出轨了。。某某软件需要升级。。哈哈。
要点
1.NotificationManager(用getSystemService获取)
+Notification(用Notification.Compat.Builder去构造)
+Notificationmanager的notify方法
(传入参数依次为id和notification对象)
2.要想点开通知栏的通知有反应,要借助PendingIntent
,通过PendingIntent类的getActivity/getBroadcase/getService
方法来获取PendingIntent对象,方法传入参数依次为Context
+0
+一个intent
(这个intent决定了PendingIntent的实际动作是什么)+0
3.构造完PendingIntent对象之后,在Builder后面连缀setContentIntent
方法,传入PendingIntent对象就可以了。点了通知之后通知还会待在那里,有两种取消方法,一种是Builder后面连缀setAutoCancle
方法传入true
,另一种是新Acitvity的onCreate方法中获取NotificationManager对象之后,调用cancle
,传入一开始notify的id
就可以取消了。(这里是以getActivity获取PendingIntent为例的,如果是getBroadcast,那就是在onReceive里面去写)
4.通知还有其他技巧,或者说不限于通知栏,如setSound
在通知发出时候播放指定音频,setVibrate
控制手机震动,setLights
控制手机前置的LED灯,setDefaults
默认的通知效果等等。
5.Builder后面还有一些其他API,如setStyle
传入一个NotificationCompat.Style
参数,可以构建长文字、图片等富文本信息。还有setPriority
设置通知优先级。
通知的基本用法
可以在活动、广播接收器或者服务里面创建通知。一般在活动里面创建通知的情况比较少或者说是不实用的,因为一般我们希望通知时候程序在后台。但不论在哪里创建,大体步骤都是一致的。
新建一个NotificationTest项目进行测试,详细步骤是这样的,首先我们需要一个NotificationManager来对通知进行管理,调用Context的getSystemService()
方法获取:
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
这个方法接受一个字符串参数用于确定获取系统的哪个服务,我们传入NOTIFICATION_SERVICE
,这样就获取了NotificationManager
的实例,下来获取Notification对象,需要一个Builder构造器:
Notification notification = new NotificationCompat.Builder(context).build();
这是创建了一个空的Notification对象,我们可以在build之前连缀任意多的设置方法创建一个丰富的Notification对象:
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.build();
这块的例子调用了五个设置方法,我们也能从方法名上猜出来这大概是在干什么。setContentTitle指定通知的标题,setContentText指定通知的正文,setWhen指定通知的时间以毫秒为单位,指定的时间会显示在通知上面,setSmallIcon指定通知小图标,小图标会显示在状态栏上面,setLargeIcon指定通知的大图标,下拉系统状态栏时候,就可以看到大图标了。设置工作完成最后调用Notification的notify
方法,让通知显示出来。这个方法接收两个参数,第一个id,需要保证每个通知指定的id都不同,第二个Notification对象,传入创建好的Notification对象即可:
manager.notify(1,notification);
下面添加一个按钮实践一下:
然后按钮点击事件:
确实有那个Builder是被弃用了,但是我们刚入门就先用着。。新的东西等学完之后看文档。
这块按钮事件申请和以前用匿名内部类不太一样,我们用了实现接口的方式,这样可能看上去更清晰一点,但是显然没有匿名类那么简洁。这里Notification部分的代码我们和上面示例里面完全一样,大小图都设置的是ic_launcher这张图。运行之后:
再按按钮:
在下拉状态栏之前会有小图标显示。我们这里由于没有设置任何点击进去的效果,所以这个通知点进去没有任何反应。接下来就要加入一些效果了。使用PendingIntent
.
PendingIntent
和Intent
其实很类似,后者侧重于立刻执行某个动作,而PedingIntent
从名字上面也看出来了,侧重于在某个合适的时机去执行动作。
PendingIntent
提供了几个静态方法用于获取PendingIntent
的实例,可以根据需求选择使用getActivity/getBroadcase/getService
。接收参数两个,第一个是Context
,第二个参数通常传入0
即可,书上也没有解释,第三个是一个Intent
对象,通过这个对象构建出PendingIntent
的“意图”,第四个参数确定PendingIntent
的行为,4个可选值,通常传入0
即可。然后我们只需要在上面那个Builder构造器后面连缀一个setContentIntent
方法,传入PendingIntent对象就可以了。
下面来实践一下,我们希望点击通知后打开一个NotificationActivity活动,那先准备这个新的活动,new里面一个Empty Activity,布局代码如下:
简单加了一个TextView,这个活动准备好之后,然后改一下点击事件:
点通知之后:
一般的通知我们都要求点完之后再状态栏的图标消失掉的。这里没有消失,我们可以采用两种方法解决:
1.builder的setAutoCancle
方法传入true
;
2.使用manager
的cancle
方法,参数是通知的id,就是在notify里面指定的那个。需要把它写在新启动的那个活动的代码里面。这样意味着活动一启动,通知就被cancle了。
想取消什么,就cancle里面传入相应的id即可。
就不演示了。
通知的进阶技巧
builder下面的API中还有可以set音频,set震动,set手机LED灯的等等。体验一下。
首先是setSound,参数是一个Uri参数,指定的引萍文件需要先获取到它对应的URI,就要用到Uri的很多静态方法。书上举例是获取了系统的一个铃声:
image按键后在模拟器上听到滴的一声响起,但在手机上没有,是权限问题?
然后还有setVibrate
这个方法接收一个数组,用于设置震动和静止的时长,以毫秒为单位,下标偶数表示静止时长,下标奇数表示震动时长,从0开始:
控制手机震动还需要在AM里面声明权限:
不过这个没法演示了。。
锁屏状态下来,有未接来电或者短信之类的,手机会有前置LED灯的通知。使用setLights,三个参数依次为灯的颜色,亮灯时长和灯暗的时长,单位均为毫秒:
也还可以什么都不干,有默认的设置,根据手机环境来决定播放铃声震动已经LED灯,用的是setDefault,传入的参数也有不同的,这就就用全部默认的NotificationCompat.DEFAULT_ALL:
通知的高级功能
除了上面几个set,这块最后再介绍几个。
setStyle
第一个是setStyle,接收一个NotificationCompat.Style参数,从这个参数可以构建富文本信息,如长文字、图片等等。也就是setStyle帮助我们的通知内容更加丰富,不仅有短文字,还可以有长文字,还可以有图片。
文字太长时候,setContentText会显示不全后面是省略号,当然原则上讲,通知往往言简意赅,但是如果真的需要一大段文字,就可以使用setStyle实现。
这里我们在setContentText搞了一大堆This is content text..可以看到后面显示不出来了:
setStyle可以解决这个问题:
</figure>
参数里面new了一个NotificationCompat.BigTextStyle对象,这个对象封装了长文字信息,调用它的bigText方法传入长字符串即可。效果如下:
刚说了还可以传图片,我记得在世界杯期间,UC浏览器推送一个世界杯的通知,在通知栏出现了那种国旗VS国旗,还有比分那种看上去很炫的通知,大概就是加入了图片元素在其中吧。这也是用setStyle可以做到,准备一个图片放在资源目录下面:
和长文字一样,这里new了一个NotificationCompat.BigPicture对象,调用它的bigPicture方法,参数是要用BitmapFactory.decodeResource方法来解码源文件,将图片解析成Bitmap对象即可。
setPriority
有时候手机上APP特别多,都会推送各种消息,但是有的在最上面,有的在下面,那么显然的,通知也有优先级,不同的通知重要程度不同。比如在你玩游戏时候QQ微信弹出消息,那种优先级比较高,会在屏幕上还显示了对方发来信息的一部分内容,而某个app的升级也有通知,这种优先级略低一些,显然不会再你打王者荣耀时候弹框出来。。。而是仅仅在状态栏有个小图标等你去点。
这个方法接收整型参数用于表示重要程度,五个常量值可以选择,PRIORITY_DEFAULT是默认值,和不设置的效果一样,PRIORITY_MIN最低的优先级,往往需要下拉状态栏才可以看到;PRIORITY_LOW较低的优先级,系统可能会将这类通知缩小,或者改变它的显示顺序排在更重要的通知后面;PRIORITY_HIGH较高的优先级,系统可能会将其放大,并排在比较靠前的位置;PRIORITY_MAX,优先级最高必须要让用户立即看到,甚至需要用户响应操作。修改完之后我们并没有看到效果。原因是Android又更新了,在这本书之后,如果App的targetSdkVersion大于等于26,且并未设置NotificaitonChannel,创建的通知是不会弹出的。
这又要涉及频道了。。暂时先搁置,突击完书上内容为主。
网友评论