Android8.0消息通知适配与点击事件从入门到放弃

文章默认大家会创建消息通知

消息通知在Android 8.0以上(targetSdkVersion大于等于26)的设备中,

  1. 添加了NotificationChannel(通知渠道)的概念,每个消息通知必须依附于通知渠道
  2. 过期了NotificationCompat.Builder(Context context) 方法,统一使用NotificationCompat.Builder(Context context, String channelId) 方法获取创建Notification的Bulider:
  3. 修改了设置通知信息优先级和多媒体的方式
NotificationChannel(String id, CharSequence name, int importance)
8.0创建消息通知的正确姿势:
创建通知
        val pushDataBean = 你的数据源
        val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        //创建通知
        val mBuilder = NotificationCompat.Builder(context, AppConfig.NOTIFICATION_CHANNEL)
                .setSmallIcon(R.drawable.ic_logo)
                .setContentTitle(pushDataBean.text)
                .setContentText(pushDataBean.title)
                .setStyle(
                        NotificationCompat
                                .BigTextStyle()
                                .setBigContentTitle(pushDataBean.title)
                                .bigText(pushDataBean.text)
                )
                .setOngoing(false)
                .setAutoCancel(true)
创建通知channel和配置通知消息
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(AppConfig.NOTIFICATION_CHANNEL, AppConfig.NOTIFICATION_CHANNEL,
                    //设置优先级
                    NotificationManager.IMPORTANCE_HIGH)
            //设置在渠道信息
            channel.name = AKApplication.instance.applicationContext.getString(R.string.notify_channel_name)
            channel.description = AKApplication.instance.applicationContext.getString(R.string.notify_channel_description)
            //绕过请勿打扰
            channel.setBypassDnd(true)
            //设置在锁屏界面上显示这条通知
            channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
            channel.setShowBadge(true)
            //设置呼吸灯
            channel.enableLights(true)
            channel.lightColor = Color.GREEN
            //设置震动
            if (pushDataBean.is_vibrate) {
                channel.enableVibration(true)
                channel.vibrationPattern = longArrayOf(100, 400, 100)
            }
            //设置铃声
            if (pushDataBean.is_ring) {
                //默认有铃声
                channel.setSound(null, null)
            }
            mNotificationManager.createNotificationChannel(channel)
        } else {
            //设置优先级
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                //8.0以下 && 7.0及以上 设置优先级
                mBuilder.priority = NotificationManager.IMPORTANCE_HIGH
            } else {
                mBuilder.priority = NotificationCompat.PRIORITY_HIGH
            }
            //设置多媒体
            if (pushDataBean.is_vibrate && pushDataBean.is_ring) {
                mBuilder.setDefaults(Notification.DEFAULT_ALL)
            } else if (pushDataBean.is_vibrate) {
                //设置震动
                mBuilder.setDefaults(Notification.DEFAULT_VIBRATE)
            } else if (pushDataBean.is_ring) {
                //设置铃声
                mBuilder.setDefaults(Notification.DEFAULT_SOUND)
            }
        }

这里需要注意的是

  1. channel配置需要在createNotificationChannel(channel)之前配置完成,一旦create就无法改变
  2. channel的name和description会在设置页面显示
  3. 被创建过的channel无法进行改变,包括声音震动配置
  4. 国产手机多媒体设置不一定会生效,需要在设置页面进行多媒体的相关配置
设置点击事件并发送通知
        //设置pendingIntent
        val intent = Intent(context, NotificationClickReceiver::class.java)
        intent.putExtra(KeySet.I_NOTIFICATION_EXTRA, dataString)
        val pendingIntent = PendingIntent.getBroadcast(context, DateUtils.instance.getNowSeconds().toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT)
        mBuilder.setContentIntent(pendingIntent)

        //发送通知
        mNotificationManager.notify(DateUtils.instance.getNowSeconds().toInt(), mBuilder.build())

NotificationClickReceiver接收广播类

class NotificationClickReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val data = intent?.getStringExtra(KeySet.I_NOTIFICATION_EXTRA)
        //处理点击消息
    }
}

不要忘记在清单文件中注册广播消息

<receiver android:name=".receiver.NotificationClickReceiver" />
要点

获取PendingIntent的方法:

  1. getActivity()
  2. getActivities()
  3. getBroadcast()
  4. getService()
  5. getForegroundService()

这些获取方法分别对应了Activity、Broadcast、Service,根据自己的具体情况选择;参数都是四个:

  1. Context
  2. requestCode:请求码
  3. Intent:请求意图用以指明启动类及数据传递
  4. flags:标志位

flags与我们传递数据息息相关:

  1. FLAG_CANCEL_CURRENT:如果已经获取到一个相同的PendingIntent对象,会先将获取的PendingIntent取消,然后重新生成一个PendingIntent对象。
  2. FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null,如果之前设置过,这次就能获取到。
  3. FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
  4. FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent相等的PendingInent,将复用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras

两个PendingIntent相等是指它们的operation一样, 且其它们的Intent的action, data, categories, components和flags都一样。但是它们的Intent的Extra可以不一样。

一般来说我们会使用FLAG_UPDATE_CURRENT更新消息通知中的数据Extras
这里分两种情况,如果我们用相同的PendingIntent,更新数据的Extras会在原有的通知消息里进行更新,而不会新建一个消息通知展示消息;如果需要多条消息并列展示,则需要不同的PendingIntent(设置不同的requestCode即可)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值