Android - 通知

一、版本变更

使用 NotificationCompat 来确保各版本API和体验统一。

Android 5

targetSdkVersion ≥ 21

图标颜色。

Android 8

targetSdkVersion ≥ 26

渠道通知。

桌面图标角标(默认开启)。

Android 13运行时权限。

二 、通知图标(Android 5)

第三方魔改ROM不会遵守,例如MIUI直接使用APP的icon。通知栏图标应该只使用alpha图层来进行绘制(图标不要带颜色,只存在透明度)而不应该包括RGB图层(ARGB只有A)。否则状态栏的图标是个白圈,下拉后通知栏图标右下角也是白圈。

//通知栏的图标无法改色,状态栏大图右下角的图标可以
builder.setColor(Color.parseColor("#EAA935"))

三、渠道通知、桌面图标角标(Android 8)

  • 为了对私信、广告、订阅...进行区分,用户可以选择性对分类进行关闭或更改重要程度,避免消息过多导致用户反感全部屏蔽或者卸载。
  • 桌面图标角标只有一个点,长按才显示数字。
渠道的重要性用户可以随时在系统设置中手动变更,APP无法后期修改。

通知栏显示效果

锁屏提示音横幅
IMPORTANCE_MAX展开
IMPORTANCE_HIGH展开
IMPORTANCE_DEFAULT展开-
IMPORTANCE_LOW展开--
IMPORTANCE_MIN折叠---
IMPORTANCE_NONE----

3.2.1 创建

不做版本判断会崩溃。Channel会覆盖Builder中相同的配置(做版本适配的话那就都要写)。 

private val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager //获取通知管理器
private val channelId = "渠道ID"  //唯一值
private val notificationId = 123456 //唯一值

//构建通知
val notification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
    createNotificationChannel(notificationManager, channelId)   //创建通知渠道
    NotificationCompat.Builder(this, channelId) //8开始通知必须分配渠道
} else {
    NotificationCompat.Builder(this)
}.setContentTitle("通知标题")
    .setContentText("通知内容")
    //设置图标角标显示数字(未读消息数)
    .setNumber(2)
    //状态栏显示的小图标
    .setSmallIcon(R.drawable.ic_launcher_foreground)
    //通知栏显示的大图标
    .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_foreground))
    //点击通知后的跳转
    //Intent一般new出来就开启,而PendingIntent不一定会开启,需要满足某些条件(getActivity()打开一个界面,getService()开起一个服务,getBroadcast()发送一个广播)。
    .setContentIntent(PendingIntent.getActivity(this, 1, Intent(), PendingIntent.FLAG_IMMUTABLE))
    //点击通知后是否清除该通知
    .setAutoCancel(true)
    //提醒方式
    .setDefaults(NotificationCompat.DEFAULT_ALL)
    //提示音
    .setSound(Uri.fromFile(File("/system/media/audio/ringtones/Luna.ogg")))
    //震动效果
    .setVibrate(longArrayOf(0, 1000, 1000, 1000))   //索引单数为静止时长,双数为震动时长
    //呼吸灯效果
    .setLights(Color.GREEN,1000,1000)   //颜色,亮起时长,熄灭时长
    //通知栏显示长文本内容
    .setStyle(NotificationCompat.BigTextStyle().bigText("长文本通知内容"))
    //通知栏显示大图片
    .setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_foreground)))
    //优先级(max>high>default>low>min)
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    .build()
//    notification.flags = NotificationCompat.FLAG_AUTO_CANCEL    //点击通知后清除该通知
//    notification.flags = NotificationCompat.FLAG_NO_CLEAR       //不允许清除该通知(常驻)

//使用
notificationManager.notify(notificationId, notification)    //开启通知
//notificationManager.cancel(notificationId)  //取消通知(也可以取消常驻)

//构建渠道
@TargetApi(Build.VERSION_CODES.O)
fun createNotificationChannel(notificationManager: NotificationManager, channelId: String){
    if (notificationManager.getNotificationChannel(channelId) == null){ //不存在该渠道才创建
        val channelName = "渠道名称"    //系统设置中用户看的
        val importance = NotificationManager.IMPORTANCE_DEFAULT //优先级, max>high>default>low>min
        val channel = NotificationChannel(channelId, channelName, importance).apply {
            //Channel会覆盖Builder中相同的配置。
            description = "渠道描述"     //系统设置中用户看的
            lightColor = Color.GREEN    //呼吸灯颜色
            enableLights(true)   //启用呼吸灯闪烁
            vibrationPattern = longArrayOf(0, 1000, 0, 1000)  //索引单数为静止时长,双数为震动时长
            enableVibration(true)   //启用震动
            setShowBadge(true)  //启用桌面图标角标(默认开启)
            lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC //锁屏显示:public显示标题+内容,private只显示标题,secret不显示
        }
        notificationManager.createNotificationChannel(channel)  //注册到系统中
    }
}

3.2.2 管理

由于APP无法后期修改渠道的重要性,像用户关闭了微信通知无法接收消息推送,可以通过判断后跳转到设置界面引导用户开启。

//在发送通知的地方调用
@TargetApi(Build.VERSION_CODES.O)
fun checkIfTurnedOff(notificationManager: NotificationManager, channelId: String) {
    val channel = notificationManager.getNotificationChannel(channelId)
    if (channel.importance == NotificationManager.IMPORTANCE_NONE) {
        Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).let {
            it.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
            it.putExtra(Settings.EXTRA_CHANNEL_ID, channel.id)
            startActivity(it)
        }
        Toast.makeText(this, "请手动将通知打开", Toast.LENGTH_SHORT).show()
    }
}

3.2.3 删除

虽然能删除,为了防止恶意APP随意创建删除(你屏蔽我这个渠道我就删了再创建),在该APP的系统通知管理界面会显示被删除渠道的数量。

四、运行时权限(Android 13)

13之前系统默认APP有通知权限可以随时发,13之后发的时候需要申请,也不能像之前那样检测被关闭后跳转引导开启。分别适配很繁琐,这里使用PermissionX。

<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    add(Manifest.permission.POST_NOTIFICATIONS)
}
//或者使用这个就不用手动判断了
add(PermissionX.permission.POST_NOTIFICATIONS)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值