Android 4.0新的广播机制FLAG_EXCLUDE_STOPPED_PACKAGES

问题: 
第三方app调起失败,固然,这个是只发现是在4.x的android系统下发生,在2.x版本下,一切正常,(实际上是3.1及以上的版本都有问题)具体场景为: 
一、第三方App安装成功但未启动,试图从App经过sendBroadcast方式调起:失败 
二、第三方App的进程被用户强制杀掉,试图从App经过sendBroadcast方式调起:失败 
三、第三方App处于启动状态,试图从App经过sendBroadcast方式调起:成功 
看了一下调起第三方app的代码逻辑,是这样的:html

Intent intent = new Intent("com.hahaha.action.INVOKE");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("type", "frs");
intent.putExtra("fname", "hahaha");
activity.sendBroadcast(intent);
  •  

因而直接定位问题:一定是高版本的android系统,在发送广播的适合,没法调起未启动(处于中止状态)的的App,打开官方文档查了一下: http://developer.android.com/about/versions/android-3.1.html#launchcontrols 写的很明白,大概意思是: 
从Android 3.1开始,给Intent定义了两个新的Flag,分别为FLAG_INCLUDE_STOPPED_PACKAGES和FLAG_EXCLUDE_STOPPED_PACKAGES,用来控制Intent是否要对处于中止状态的App起做用,顾名思义: 
FLAG_INCLUDE_STOPPED_PACKAGES:表示包含未启动的App 
FLAG_EXCLUDE_STOPPED_PACKAGES:表示不包含未启动的App 
值得注意的是,Android 3.1开始,系统向全部Intent的广播添加了FLAG_EXCLUDE_STOPPED_PACKAGES标志。这样作是为了防止广播无心或没必要要地开启未启动App的后台服务。若是要强制调起未启动的App,后台服务或应用程序能够经过向广播Intent添加FLAG_INCLUDE_STOPPED_PACKAGES标志来唤醒,示例代码:android

Intent intent = new Intent("com.hahaha.action.INVOKE"); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent. FLAG_INCLUDE_STOPPED_PACKAGES);
intent.putExtra("type", "frs");
intent.putExtra("fname", "hahaha");
activity.sendBroadcast(intent);

若是你的项目依赖的Android SDK是3.1如下版本,那么直接像上面这样写是会出问题的,你会发现Intent.FLAG_INCLUDE_STOPPED_PACKAGES没法被正确识别,因此相对安全的办法是,直接把value写进来:安全

Intent intent = new Intent("com.hahaha.action.INVOKE"); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 3.1之后的版本直接设置Intent.FLAG_INCLUDE_STOPPED_PACKAGES的value:32
if (android.os.Build.VERSION.SDK_INT >= 12) {
    intent.setFlags(32);
}
intent.putExtra("type", "frs");
intent.putExtra("fname", "hahaha");
activity.sendBroadcast(intent);
相关文章
相关标签/搜索