8.0以上無法接收隱式廣播
阿新 • • 發佈:2018-12-09
APP傳送的隱式廣播連自己也收不到,0上限制。
log如下:
08-23 21:45:38.271 1207 1225 W BroadcastQueue: Background execution not allowed: receiving Intent { act=com.xxx.xxx flg=0x10 (has extras) } to com.xx.xx/com.xx.xx.receiver.XxReceiver
BroadcastQueue.java中的限制程式碼:
if (!skip) { final int allowed = mService.getAppStartModeLocked( info.activityInfo.applicationInfo.uid, info.activityInfo.packageName, info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false); if (allowed != ActivityManager.APP_START_MODE_NORMAL) { // We won't allow this receiver to be launched if the app has been // completely disabled from launches, or it was not explicitly sent // to it and the app is in a state that should not receive it // (depending on how getAppStartModeLocked has determined that). if (allowed == ActivityManager.APP_START_MODE_DISABLED) { Slog.w(TAG, "Background execution disabled: receiving " + r.intent + " to " + component.flattenToShortString()); skip = true; } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0) || (r.intent.getComponent() == null && r.intent.getPackage() == null && ((r.intent.getFlags() & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0) && !isSignaturePerm(r.requiredPermissions))) { mService.addBackgroundCheckViolationLocked(r.intent.getAction(), component.getPackageName()); Slog.w(TAG, "Background execution not allowed: receiving " + r.intent + " to " + component.flattenToShortString()); skip = true; } } }
程式碼說明:
1.只要intent的flag包含FLAG_RECEIVER_EXCLUDE_BACKGROUND則不允許該廣播被接收。
2.對於隱式廣播,如果沒有包含FLAG_RECEIVER_INCLUDE_BACKGROUND也不允許被接收。
繞過的思路就是將所有傳送出去的廣播都加上FLAG_RECEIVER_INCLUDE_BACKGROUND標誌:
程式碼如下:
public class BroadcastPassedby { public static void enableImplicit(){ try { if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O){ return; } ActivityManager am = (ActivityManager)EmmCore.getContext().getSystemService(Context.ACTIVITY_SERVICE); Object activityManager = Reflect.on(am).call("getService").get(); Object proxy = Proxy.newProxyInstance(activityManager.getClass().getClassLoader(),activityManager.getClass().getInterfaces(),new ActivityManagerHandler(activityManager)); Reflect.on(am).field("IActivityManagerSingleton").set("mInstance",proxy); }catch (Exception e){ e.printStackTrace(); } } private static class ActivityManagerHandler implements InvocationHandler{ private Object mActivityManager; public ActivityManagerHandler(Object activityManager) { mActivityManager = activityManager; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("broadcastIntent")){ for(Object o : args){ if(o == null){ continue; } if(o instanceof Intent){ Intent intent = (Intent)o; int includeBackground = Reflect.on(Intent.class).field("FLAG_RECEIVER_INCLUDE_BACKGROUND").get(); intent.setFlags(intent.getFlags()| includeBackground); } } } return method.invoke(mActivityManager,args); } } }