Android8.0开始引入了通知渠道的概念,每条通知都要属于一个对应的渠道,每个应用程序都可以自由的创建当前应用拥有哪些通知渠道,但这些通知渠道的控制权是掌握在用户手上的,用户可以自由地选择这些通知渠道的重要程度,是否响铃、是否震动或者是否要关闭这个渠道的通知。
对于每个应用来说,通知渠道的划分是非常讲究的,因为一旦创建后就不能再修改了,如果一开始给A通知渠道设置了低优先级,后续即使更新软件把A通知渠道改成高优先级也不会生效。因此开发者需要仔细分析自己的应用程序一共有哪些类型的通知,然后再去创建相应的通知渠道。
创建通知首先需要一个NotificationManager对通知进行管理,可以通过调用Context的getSystemService()方法获取,它接收一个字符串参数用于确定获取哪个系统服务,这里传入Context.NOTIFICATION_SERVICE即可获取。
NotificationManager的完整实例如下:
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
接下来要使用NotificationChannel类构建一个通知渠道,并调用NotificationManager的createNotificationChannel()方法完成创建。由于NotificationChannel和createNotificationChannel()都是Android8.0中新增的API,所以还需要进行版本判断:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId,channelName,importance)
manager.createNotificationChannel(channel)
}
创建一个通知渠道至少需要渠道ID、渠道名称、重要等级三个参数,其中ID可以随便定义,只要保证全局唯一即可。渠道名称是给用户看的,用于表达这个渠道的用途。通知等级主要有IMPORTANCE_HIGH、IMPORTANCE_DEFAULT、IMPORTANCE_LOW、IMPORTANCE_MIN这几种,对应重要程度从高到低。不过用户也可以随时手动更改某个通知渠道重要等级,只有IMPORTANCE_HIGH高等级可以在用户手机上弹出通知弹窗。
一、通知的基本用法
通知可以在Activity、BroadcastReceiver、Service中创建,相比BroadcastReceivcer和Service,在Activity中创建通知的场景还是比较少的,因为一般只有应用进入后台才需要使用通知。
需要使用NotificationCompat类的build()构造器来构造一个Notification对象,使用AndroidX的NotificationCompat类可以保证软件在所有Android系统版本上运行。
class MainActivity : AppCompatActivity() {
override fun onCreate(...) {
...
val manager = getSystemService(Context.NOTIFICATION_SERVICE)
as NotificationManager
// 判断客户机版本是否大于等于Androud8.0
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 创建通知渠道
val channel = NotificationChannel("normal","Normal",
NotificationManager.IMPORTANCE_DEFAULT)
manager.createNotificationChannel(channel)
}
btn.setOnClickListener {
val notification = NotificationCompat.Builder(this,"normal")
.setContentTitle("这是通知标题")
.setContentText("这是通知内容")
// 设置通知栏小图标
.setSmallIcon(R.drawable.small_icon)
// 设置下拉通知大图标
.setLargeIcon(BitmapFactory.decodeResource(resources,
R.drawable.large_icon))
.build()
// 手机显示通知,第一个参数是id,保证唯一性
manager.notify(1, notification)
}
}
}
1.PendingIntent——给通知指明意图
PendingIntent和Intent有些类似,都可以启动Activity、Service以及发送广播,不同的是Intent倾向于立即执行某个动作,而PendingIntent倾向于在某个合适的时机执行某个动作,比如点击通知启动Activity。
PendingIntent提供了三个静态方法用于获取实例,可以根据需求选择getActivity()、getBroadcase()、getService(),这三个方法接收的参数是相同的,第一个参数是Context;第二个参数一般用不到,传入0即可;第三个参数是一个Intent对象,用于构建出PendingIntent的“意图”;第四个参数用于确定PendingIntent的行为,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT、FLAG_UPDATE_CURRENT四个值可选,通常传入0即可。
NotificationCompat.Builder还可以连缀一个setContentIntent()方法,用于传入PendingIntent对象。
override fun onCreate(...) {
...
btn.setOnClickListener {
// 构建PendingIntent“意图”Intent
val intent = Intent(this,NotificationActivity::class.java)
// 用getActivity()构建PendingIntent
val pi = PendingIntent.getActivity(this, 0, intent, 0)
val notification = NotificationCompat.Builder(this,"normal")
...
// 设置通知“意图”
.setContentIntent(pi)
.build()
manager.notify(1, notification)
}
}
2.取消通知在状态栏中显示
第一种方法是,用户点击通知后自动取消。
val notification = NotificationCompat.Builder(this,"normal")
...
// 点击通知后自动取消
.setAutoCancel(true)
.buile()
第二种方法是,用代码显式取消
val manager = getSystemService(Context.NOTIFICATION_SERVICE)
as NotificationManager
btn.setOnClickListener {
// 1是创建通知(manager.notify())时传入的id
manager.cancel(1)
}
二、通知的进阶技巧
挑一些常用的API进行学习。先来看看setStyle()方法,这个方法允许我们构建出富文本通知内容,也就是说通知不光可以有文字和图标。setStyle()方法接收一个NotificationCompat.Style方法,这个参数就是用来构建具体的富文本信息的,如长文字、图片等。
1.长文本显示
如果文本过长还是建议在Activity中显示更合理。
val notification = NotificationCompat.Builder(this,"normal")
...
.setStyle(NotificationCompat.BigTextStyle().bigText(
"Learn how to build notifications, send and sync data" +
"and use voice actions. Get the official Android" +
"IDE and developer tools build apps for Android."))
.build()
2.大图片显示
val notification = NotificationCompat.Builder(this,"normal")
...
.setStyle(NotificationCompat.BigPictureStyle().bigPicture(
BitmapFactory.decodeResource(resources,
R.drawable.big_image)))
.build()