dnd 辅助 android,对Android 8.0以上版本通知点击无效的一次分析

版权声明:本文为xing_star原创文章,转载请注明出处!

对Android 8.0以上版本通知点击无效的一次分析

最近在重构聊天服务,有机会从新梳理下前人写的通知相关的逻辑,隐藏着一个很深的bug,遗留了应该有8个多月了。直到今天才定位出原因,之前一直怀疑是自己设备的问题????,经过写demo,做实验验证,最终得出结论。

Android 8.0之后通知相关的Api又发生了很大的变化,接手项目的时候,没怎么关注过这块,一直以为没有问题,到今天测试验证,发现还是存在问题的??,问题表象是,点击App通知栏的通知消息,点击之后通知栏还在,一直没有反应(App业务中关于Click通知栏的逻辑没有生效)。抱着对代码怀疑的角度,自己创建了个demo工程,参考Notification的用法,自己做实验观察效果。

实验过程

这里在回顾下自己做实验的过程。

首先创建了个demo工程,添加通知相关的代码,以及动态注册了一个BroadcastReceiver。

private final BroadcastReceiver mBroadcastReceiver = newBroadcastReceiver() {

@Overridepublic voidonReceive(Context context, Intent intent) {if (intent == null || context == null) {return;

}

mNotificationManager.cancel(NOTIFICATION_ID_LIVE);

String type=intent.getStringExtra(PUSH_TYPE);if(PUSH_TYPE_LINK.equals(type)) {

mNumLinkes= 0;

}else if(PUSH_TYPE_LIVE.equals(type)) {

mNumLives= 0;

}//这里可以重新计数

}

};

private voidregisterHeadsetPlugReceiver() {

IntentFilter intentFilter= newIntentFilter();

intentFilter.addAction(NOTIFICATION_CLICK_ACTION);

intentFilter.addAction(NOTIFICATION_DELETED_ACTION);

registerReceiver(mBroadcastReceiver, intentFilter);

}

private voidsendLiveNotification() {

Intent intent= newIntent(NOTIFICATION_CLICK_ACTION);if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.O) {

NotificationChannel channel= newNotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);

channel.setBypassDnd(true); //设置绕过免打扰模式

channel.canBypassDnd(); //检测是否绕过免打扰模式

channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);//设置在锁屏界面上显示这条通知

channel.setDescription("测试通知消息内容");

channel.setLightColor(Color.GREEN);

channel.setName("测试通知消息名称");

channel.setShowBadge(true);

channel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});

channel.enableVibration(true);

mNotificationManager.createNotificationChannel(channel);

}

NotificationCompat.Builder mBuilder= new NotificationCompat.Builder(this, CHANNEL_ID);

String title= "Push测试";

mBuilder.setContentTitle(title);

mBuilder.setTicker(title);

mBuilder.setContentText("https://233.tv/over140");

mBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));

mBuilder.setSmallIcon(R.mipmap.ic_launcher);

mBuilder.setDefaults(Notification.DEFAULT_ALL);

mBuilder.setWhen(System.currentTimeMillis());

mBuilder.setContentIntent(PendingIntent.getBroadcast(this, NOTIFICATION_ID_LIVE, intent, 0));

mBuilder.setDeleteIntent(PendingIntent.getBroadcast(this, NOTIFICATION_ID_LIVE, new Intent(NOTIFICATION_DELETED_ACTION).putExtra(PUSH_TYPE, PUSH_TYPE_LIVE), 0));

mNotificationManager.notify(NOTIFICATION_ID_LIVE, mBuilder.build());

}

第一步的测试代码比较简单,在MainActivity调用sendLiveNotification()方法,就会出现通知栏,之后呢,点击通知栏会发送广播,我们在MainActivity注册了这个广播事件,就能够接收到,看起来没问题。到这里把怀疑点放到了静态注册上,BroadcastReceiver在AndroidManifest.xml中的注册。

接着就是修改代码,把动态注册的代码调整为一个CustomBroadcastReceiver,然后在AndroidManifest.xml中进行注册

public class CustomBroadcastReceiver extendsBroadcastReceiver {private int NOTIFICATION_ID_LIVE = 101;private String PUSH_TYPE_LIVE = "PUSH_TYPE_LIVE";private String PUSH_TYPE = "push_type";private String PUSH_TYPE_LINK = "PUSH_TYPE_LINK";private intmNumLinkes;private intmNumLives;

@Overridepublic voidonReceive(Context context, Intent intent) {

NotificationManager mNotificationManager=(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);if (intent == null || context == null) {return;

}

mNotificationManager.cancel(NOTIFICATION_ID_LIVE);

String type=intent.getStringExtra(PUSH_TYPE);if(PUSH_TYPE_LINK.equals(type)) {

mNumLinkes= 0;

}else if(PUSH_TYPE_LIVE.equals(type)) {

mNumLives= 0;

}

}

}

调整完后,继续验证自己的想法。

运行程序,开启debug模式,发现点击通知栏后,在CustomBroadcastReceiver中没有拦截到,到这里就确定了问题肯定是出现在静态注册上面,但是之前的项目中,有些第三方的broadcastReceiver是静态注册,但最终是执行了onReceiver的方法,那肯定是我的使用姿势有问题。于是google搜索了一番,关键词就是android broadcastreceiver androidmanifest android 8.0 不运行,第一篇文章就是我想要找的。参考了一番,发现提到的几个说法值得一试,目前只验证了

intent.setPackage(getPackageName());

在查阅资料的过程也特意观察了下log输出

07-26 23:30:14.452 1637-1688/? W/BroadcastQueue: Background execution not allowed: receiving Intent { act=me.star.notificationdemo2.click flg=0x10 } to notification.star.me.notificationdemo2/.CustomBroadcastReceiver

说的是后台执行不被允许?反正搞不懂啥情况,没仔细看相关的源码。加上intent.setPackage(getPackageName());后重新编译

之后重新debug,发现这次执行了onReceiver的代码逻辑,终于找到了问题所在,就这一行代码,花去了好几个小时??,但是值得的。

参考资料

Demo下载

链接:https://pan.baidu.com/s/1Ac97_0kFxKavpQi6-YxB2w 密码:niun  (demo中包含Git版本控制,可以通过切换commit,查阅动态注册,静态注册的代码)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值