Background execution not allowed---8.0以上送信された暗黙的なブロードキャストが受信できないことを解決
4330 ワード
target>=26の場合、アプリで送信された暗黙的な放送は自分でも受信できず、0に制限されます.
エラーログは次のとおりです.
BroadcastQueue.JAvaの制限コード:
コードの説明:
1.intentのflagがFLAGを含む限りRECEIVER_EXCLUDE_BACKGROUNDは、ブロードキャストの受信を許可しない.
2.暗黙放送の場合、FLAG_が含まれていない場合RECEIVER_INCLUDE_BACKGROUNDも受信を許さない.
迂回的な考え方は、送信されたすべての放送にFLAGを加えることです.RECEIVER_INCLUDE_BACKGROUNDフラグ:
コードは次のとおりです.
原理はHookがAMSを作ったので、アプリも何も変更する必要はありません.ApplicationでBroadcastPassedbyを呼び出すだけです.enableImplicit()でいいです.
エラーログは次のとおりです.
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);
}
}
}
原理はHookがAMSを作ったので、アプリも何も変更する必要はありません.ApplicationでBroadcastPassedbyを呼び出すだけです.enableImplicit()でいいです.