概述
通知是 Android 系统中比较有特色的一个功能,当某个应用程序希望向用户发送提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知以后,手机最上方的状态栏会显示一个通知的图标,下拉状态栏后可以看到通知的详细内容
创建通知渠道
设计通知必须以不打扰到用户为前提,否则效果会适得其反。对于应用程序发送的通知,用户并非都会感兴趣。以微博为例,我只希望收到我所关注的人的微博更新通知,但并不想让微博一天到晚给我推送一些明星的花边新闻。于是,Android 8.0 系统引入了通知渠道这个概念
通知渠道,顾名思义,就是每条通知都要属于一个对应的渠道。每个应用程序都可以自由地创建当前应用拥有哪些通知渠道,但这些通知渠道的控制权是掌握在用户手上的。用户可以自由选择这些通知渠道的重要程度,并自行决定是否关闭这个渠道的通知
对于应用来说,通知渠道的划分是非常考究的,因为通知渠道一旦创建之后就不能再修改了
通知的使用
了解完通知渠道以后,我们来通过一个实例学习一下通知的使用方法
通知的用法很灵活,既可以在 Activity 里创建,也可以在 BroadcasterReceiver 里创建,当然还可以在 Service 里创建。在 Activity 里创建通知的场景比较少,一般只有当程序进入后台的时候才需要使用通知
假设现在有一个按钮,用于发出一条通知,代码如下:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("normal", "Normal", NotificationManager.IMPORTANCE_DEFAULT)
manager.createNotificationChannel(channel)
}
button.setOnClickListener {
val notification = NotificationCompat.Builder(this, "normal")
.setContentTitle("This is content title")
.setContentText("This is content text")
.setSmallIcon(R.drawable.small_icon)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
.setAutoChannel(true)
.build()
manager.notify(1, notification)
}
}
至此,点击按钮,就会发出一条通知了。但当我们点击这条通知时,却发现没有任何效果。这是因为,要想实现通知的点击效果,还需要在代码中进行相关设置,这就涉及一个新的概念 —— PendingIntent
PendingIntent 从名字上看起来和 Intent 有些类似,都可以指明某一个意图,都可以用于启动 Activity、启动 Service 以及发送广播。不同的是,Intent 倾向于立即执行某个动作,而 PendingIntent 倾向于在某个合适的时机执行某个动作,所以也可以把 PendingIntent 简单地理解为延迟执行的 Intent
NotificationCompact.Builder 还可以连缀一个 setContentIntent() 方法,接收的参数正是一个 PendingIntent 对象,当用户点击这条通知时,就会执行相应的逻辑
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("normal", "Normal", NotificationManager.IMPORTANCE_DEFAULT)
manager.createNotificationChannel(channel)
}
button.setOnClickListener {
val intent = Intent(this, NotificationActivity::class.java)
val pi = PendingIntent.getActivity(this, 0, intent, 0)
val notification = NotificationCompat.Builder(this, "normal")
.setContentTitle("This is content title")
.setContentText("This is content text")
.setSmallIcon(R.drawable.small_icon)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
.setContentIntent(pi)
.build()
manager.notify(1, notification)
}
}
}
|