Broadcast的Intent中塞入INTENT_NEW_TASK引发的兼容性问题
来源:互联网 发布:人可以有多色 知乎 编辑:程序博客网 时间:2024/06/05 23:05
0. 起源
在做通知栏时,因为需要做点击通知栏做一些非启动Activity的操作,因此需要通过如下代码接受点击通知栏事件的广播
Intent clickIntent = new ntent(mContext,NotificationClickReceiver.class);PendingIntent contentIntent = PendingIntent.getBroadcast(mContext, STOP_NOTIFICATION_ID,clickIntent,PendingIntent.FLAG_CANCEL_CURRENT);mNotificationBuilder.setContentIntent(contentIntent); I
这样的代码本身是没有问题的,但是因为在htc的某个rom下会出现在kill掉app后,通过startForeground启动的通知栏在点击的时候,无法正常接受和发送广播(原因是因为点击后会重新启动一个新的进程运行应用)。
具体点击跳转到stack-overflow查看.
因此需要在clickIntent中加入
clickIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_NEW_TASK);
1. 引发的问题
在4.4以下的机子下会出现crash,日志如下
java.lang.RuntimeException:Unable to start service com.flamingo.gpgame.service.GPDownloadService@4197e5e0 with Intent { cmp=com.flamingo.gpgame/.service.GPDownloadService (has extras) }: java.lang.IllegalArgumentException: Can't use FLAG_RECEIVER_BOOT_UPGRADE here
具体就是因为发送的广播Intent不能有FLAG_RECEIVER_BOOT_UPGRADE
这个flags,我们的app不具备这种flags广播发送的权限。
2. 原因探寻
在我们的Intent中其实并没有添加FLAG_RECEIVER_BOOT_UPGRADE
这个flag,只是添加了Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_NEW_TASK
这三种flag,通过搜索资料发现,原来是因为谷歌工程师粗心大意把Intent.FLAG_ACTIVITY_NEW_TASK
和Intent. FLAG_RECEIVER_BOOT_UPGRADE
的常量混淆了,系统就误认为我们发送了Intent. FLAG_RECEIVER_BOOT_UPGRADE
这个广播。
具体点击跳转到stack-overflow查看.
通过分析源码也验证这上面的说法,在android-15的源码中
/** * <strong>Do not use this flag unless you are implementing your own * top-level application launcher.</strong> Used in conjunction with * {@link #FLAG_ACTIVITY_NEW_TASK} to disable the * behavior of bringing an existing task to the foreground. When set, * a new task is <em>always</em> started to host the Activity for the * Intent, regardless of whether there is already an existing task running * the same thing. * * <p><strong>Because the default system does not include graphical task management, * you should not use this flag unless you provide some way for a user to * return back to the tasks you have launched.</strong> * * <p>This flag is ignored if * {@link #FLAG_ACTIVITY_NEW_TASK} is not set. * * <p>See * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back * Stack</a> for more information about tasks. */ public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000; public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x08000000;
发现FLAG_ACTIVITY_MULTIPLE_TASK
和FLAG_RECEIVER_BOOT_UPGRADE
的常量值是一致的,而注释中也提到FLAG_ACTIVITY_NEW_TASK
是会覆盖FLAG_ACTIVITY_MULTIPLE_TASK
的值,因此可以猜想处理中应该是FLAG_ACTIVITY_NEW_TASK
包含了FLAG_ACTIVITY_MULTIPLE_TASK
,系统也会认为赋值了FLAG_ACTIVITY_NEW_TASK
的flags会拥有FLAG_RECEIVER_BOOT_UPGRADE
的属性。
上述stack-overflow提到在android-19以后的版本修复了这个问题,查看源码发现确实是这样的,常量已经改变了值,以防冲突。
public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x02000000;
3.解决方式
因为在实际应用中既要解决htc那个rom的奇葩问题,又要保证Android 4.4以下的机子正常运行,只能通过版本判断来区分是否添加flag(幸好Htc的rom是基于Android 4.4)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { clickIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);}
当然,保险的方法是在平时的使用中不要在广播的Intent中添加Intent.FLAG_ACTIVITY_NEW_TASK
,最保险的就是连Intent.FLAG_ACTIVITY_XX
的值都不要添加。
- Broadcast的Intent中塞入INTENT_NEW_TASK引发的兼容性问题
- Android中Broadcast的Intent大全
- Android中Broadcast的Intent大全
- Android中Broadcast的Intent大全
- Android中Broadcast的Intent大全
- android-Broadcast 中,启动intent 的方法。(第一版)
- intent 和 Broadcast Receiver之间的通信
- Activity. Intent. Service. Broadcast的使用
- 静态定义的receiver接收broadcast intent
- Broadcast Intent实现的四个步骤
- 查看那个broadcast发的intent
- jstl中当塞入控件的值为数字时,但界面显示为汉字时
- Android 中 Intent.ACTION_PACKAGE_ADDED 之类的 broadcast 可被声明在 manifest 中的 receiver 接收吗?
- AjaxPro由于汉字目录引发的IE兼容性问题
- 不是所有的牛奶(以android.intent.action*开头的broadcast)都叫特仑苏(protected-broadcast)
- 安卓的intent,activity,service,broadcast,broadcastreceiver
- Qdemo中broadcast的例子
- js中event的兼容性问题
- XML操作
- sql中where 1=1
- 动态创建标签
- 赋予普通用户sudo的权限方法
- 网站开发(四)后台的页面导入
- Broadcast的Intent中塞入INTENT_NEW_TASK引发的兼容性问题
- Myeclipse 误删项目文件怎么恢复!
- Java实现单链表的插入、删除、计算链表的长度和输出链表
- 【Linux】CentOS7.0打开端口
- 自动化测试模型
- 图论--最短路径问题--Dijkstra算法和Floyd算法
- Jquery+AJAX的结合使用
- APP微信支付集成——PHP
- windows 磁盘分区