一.前言
在如今五花八门的 app 中,从手机上方弹出的通知消息可谓随处可见,因此在 android 开发中掌握 Notification 知识点是很有必要的。
二.Notification基本介绍
在这里借用官方文档中的一张图
由此可见,构成一个通知的基本要素有6点:
1.小图标,通常和应用图标一样2.应用名称(系统提供)3.时间戳,用来显示通知发出的时刻4.大图标5.通知标题6.通知文本内容
这是比较常见的样式,后面还会提到其他通知样式。
那我们先来试试上边这种最简单的通知吧。
三.简单Notification的创建并显示
首先来创建一条通知,将其中的基本元素给搭建好
val builder = NotificationCompat.Builder(this, channelId).apply {
//设置通知标题
setContentTitle("通知")
//设置文本内容
setContentText("这是一条悬浮通知")
//设置小图标
setSmallIcon(R.drawable.ic_baseline_accessibility_new_24)
//true 表示户点按通知后自动移除通知
setAutoCancel(true)
//设置优先级
priority = NotificationCompat.PRIORITY_HIGH
}
其中的 setPriority() 是用于确定通知在 Android 7.1 和 更低版本 上的干扰程度。换句话说,就是显示通知的优先级。
优先级分为:
PRIORITY_MIN,PRIORITY_LOW,PRIORITY_DEFAULT,PRIORITY_HIGH,PRIORITY_MAX。
Google 建议只有非常重要的通知或者需要用户回复的通知才使用PRIORITY_HIGH和PRIORITY_MAX。但国内的很多应用不管什么通知,都要弹出来烦你一下,用户体验真的很差,所以请大家考虑自己的通知是否真的重要。
而在 Android 8.0以后,都是需要设置 通知渠道 的,否则通知不会生效。
首先通过向 createNotificationChannel() 传递 NotificationChannel 的实例在系统中注册应用的通知渠道。
//创建 NotificationChannel 实例
val channel = NotificationChannel(channelId, "name", NotificationManager.IMPORTANCE_HIGH)
val notificationManager =
this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
//在系统中注册通知渠道
notificationManager.createNotificationChannel(channel)
IMPORTANCE_HIGH 相当于高版本后代替了 PRIORITY_HIGH。
这时,我们就在系统中成功注册了通知渠道,完成了关键性的一步,我们可以看到应用设置中多了我们刚刚建立的名为 name 的通知渠道。
最后就可以显示出一条最简单的通知了,但是 notificationId 一定要记住, 因为后期取消和更新通知,都要用到此id。
notificationManager.notify(notificationId, builder.build())
注:如果按照上述操作依然无法弹出通知,请在应用详情中将 横幅 选项选中。
此外,如果想让您的应用在点击后发生响应,如跳转到指定页面,请在创建 builder 的时候使用 setContentIntent()。
//创建 intent 实现跳转
val intent = Intent(this, MainActivity::class.java)
//0 是 requestCode(请求码)
//如果要想在 intent 中传递数据并及时更新,一定要保证每次请求码都需要不同!!
//并且标明 FLAG 为 FLAG_IMMUTABLE
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
val builder = NotificationCompat.Builder(this, channelId).apply {
....
setContentIntent(pendingIntent)
}
PendingIntent 是 Intent 的封装,它自带一个 Context 对象,通常用来完成未来发生的意图,而 Intent 是即时启动,随 activity 的消失而消失。它主要与 intent 配合使用, 用来启动一些组件,从 PendingIntent 的三种创建方法就能看出:
PendingIntent.getActivity(),PendingIntent.getService(),PendingIntent.getBroadcast()。
如果我们想在后台定时发起通知,通常选择 PendingIntent.getBroadcast(),下面的回复通知中,我们将会用到。而在这里我们说要实现界面跳转,当然就选择 PendingIntent.getActivity()。
三.其他样式的Notification
其实大多时候上面那一种通知已经够用了,下面再提提其它样式的通知吧。
1.展开式通知
val builder = NotificationCompat.Builder(this, channelId).apply {
....
.setStyle(NotificationCompat.BigTextStyle()
.bigText(getText)
}
在展开前和一般的 Notification 一样:
但是右上方有一个箭头可以展开,我们看到这里有更多的文字内容。
2.带有输入框的通知
这种通知,只需要在最开始的那种通知上,加入一个输入框即可
// KEY -- 在回复操作中 intent 存储文本内容的键
val remoteInput = RemoteInput.Builder(KEY).run {
setLabel("回复")
build()
}
//设置回复图标并将创建好的 RemoteInput 设置上去
val action = NotificationCompat
.Action.Builder(R.drawable.ic_baseline_4k_24, "回复", replyPendingIntent)
.addRemoteInput(remoteInput).build()
}
上述的 replyPendingIntent 创建方式和之前的 PendingIntent 一样,只不过我们回复的消息文本用 put() 储存到里面,而上面说到的 KEY 就是这个文本值的键。
val builder = NotificationCompat.Builder(this, channelId).apply {
....
setAction()
这样一来就可以看效果了:
这样一来,我们不需要打开应用也能即时回对方消息了。但是对方怎么收到我们发出去的通知呢?
还记得上面说到的 replyPendingIntent 吗?我们通过它向广播传递过去了附带文本信息的intent,这时候我们就可以在广播中的 onReceive() 中收到这个 intent 了,然后就可以用 getResultFromIntent() 拿到文本内容了。
private fun getMessageText(intent: Intent): CharSequence? {
return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY)
}













网友评论