Android 隱式廣播

從Android O(Android 8.0)開始税娜,Android限制了隱式廣播的接收(https://developer.android.com/about/versions/oreo/background
),在開發(fā)過程中遇到“Background execution not allowed: receiving”log輸出况脆,梳理具體情況如下

哪些情況受到影響?

1.隱式發(fā)送的廣播 撩笆,一般為AndroidManifest.xml中靜態(tài)注冊的Receiver
這種類型一般是隱式的乃沙,即發(fā)送方?jīng)]有指明接收者
(注意但如果是上述靜態(tài)注冊的Receiver但發(fā)送者指明了接收者猎塞,這類廣播還是能收到的)

哪些情況不受影響?

1.發(fā)送方:顯式廣播 蔓罚,即發(fā)送方發(fā)送廣播的時候指明接收者
通過Intent setPackage或Intent setComponent
2.接收方:Receiver接收者動態(tài)注冊的方式
通過registerReceiver的方式
3.發(fā)送方:發(fā)送廣播的時候添加了FLAG_RECEIVER_INCLUDE_BACKGROUND的flag
4.接收方:發(fā)送的廣播需要接收者有權(quán)限校驗椿肩,并且這個權(quán)限是系統(tǒng)定義并且安全級別為僅簽名 (signature)的
這個有點坑瞻颂,查看google的提交記錄,他們早期考慮是第三方也適用的郑象,只要這個廣播有權(quán)限校驗便不受限制贡这,后來
最后的版本添加了只有系統(tǒng)定義的權(quán)限才適用

   /**
     * Return true if all given permissions are signature-only perms.
     */
    final boolean isSignaturePerm(String[] perms) {
        if (perms == null) {
            return false;
        }
        IPackageManager pm = AppGlobals.getPackageManager();
        for (int i = perms.length-1; i >= 0; i--) {
            try {
                PermissionInfo pi = pm.getPermissionInfo(perms[i], "android", 0);
                if (pi == null) {
                    // a required permission that no package has actually
                    // defined cannot be signature-required.
                    return false;
                }
                if ((pi.protectionLevel & (PermissionInfo.PROTECTION_MASK_BASE
                        | PermissionInfo.PROTECTION_FLAG_PRIVILEGED))
                        != PermissionInfo.PROTECTION_SIGNATURE) {
                    // If this a signature permission and NOT allowed for privileged apps, it
                    // is okay...  otherwise, nope!
                    return false;
                }
            } catch (RemoteException e) {
                return false;
            }
        }
        return true;
    }

5.系統(tǒng)發(fā)送的部分廣播 :系統(tǒng)白名單的廣播不受影響
系統(tǒng)發(fā)送這些廣播的時候帶了 FLAG_RECEIVER_INCLUDE_BACKGROUND標志的廣播:
https://developer.android.google.cn/guide/components/broadcast-exceptions
配置白名單:
源碼目錄/frameworks/base/data/etc/framework-sysconfig.xml

        if (action != null) {
            if (getBackgroundLaunchBroadcasts().contains(action)) {
                if (DEBUG_BACKGROUND_CHECK) {
                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
                }
                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
            }

6.發(fā)送方:PendingIntent.getBroadcast
通過查看系統(tǒng)源碼邏輯(安全方面考慮),這種方式是顯式發(fā)送

    @UnsupportedAppUsage
    public static PendingIntent getBroadcastAsUser(Context context, int requestCode,
            Intent intent, int flags, UserHandle userHandle) {
        String packageName = context.getPackageName();
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                context.getContentResolver()) : null;
        try {
            intent.prepareToLeaveProcess(context);
            IIntentSender target =
                ActivityManager.getService().getIntentSender(
                    ActivityManager.INTENT_SENDER_BROADCAST, packageName,
                    null, null, requestCode, new Intent[] { intent },
                    resolvedType != null ? new String[] { resolvedType } : null,
                    flags, null, userHandle.getIdentifier());
            return target != null ? new PendingIntent(target) : null;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
7.APP:APP升級了targetsdk>=26,但是跑在Android 0以下的機器厂榛,自然沒有這個特性 

解決方法

1.接收方:動態(tài)注冊
2.接收方:使用JobScheduler(網(wǎng)絡狀態(tài)等條件可替代部分廣播功能盖矫,注意國內(nèi)os對后臺特性的修改)
2.發(fā)送方:發(fā)送廣播時增加FLAG_RECEIVER_INCLUDE_BACKGROUND標志
3.接收方:添加權(quán)限校驗(對第三方應用不適用)
4.常駐后臺應用中轉(zhuǎn)(對第三方應用不適用)

技術(shù)細節(jié)與原理

限制隱式廣播的關鍵代碼邏輯如下 (BroadcastQueue.java)

             } 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;
                }
            }
        }

為什么動態(tài)注冊的廣播不受限制?
通過查看系統(tǒng)源碼BroadcastQueue的邏輯得知

參考:
http://www.reibang.com/p/c0458738d97d

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末击奶,一起剝皮案震驚了整個濱河市辈双,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柜砾,老刑警劉巖湃望,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異局义,居然都是意外死亡喜爷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門萄唇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來檩帐,“玉大人,你說我怎么就攤上這事另萤∨让埽” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵四敞,是天一觀的道長泛源。 經(jīng)常有香客問我,道長忿危,這世上最難降的妖魔是什么达箍? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮铺厨,結(jié)果婚禮上缎玫,老公的妹妹穿的比我還像新娘。我一直安慰自己解滓,他們只是感情好赃磨,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著洼裤,像睡著了一般邻辉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天值骇,我揣著相機與錄音莹菱,去河邊找鬼。 笑死雷客,一個胖子當著我的面吹牛芒珠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播搅裙,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼皱卓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了部逮?” 一聲冷哼從身側(cè)響起娜汁,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎兄朋,沒想到半個月后掐禁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡颅和,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年傅事,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峡扩。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹭越,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出教届,到底是詐尸還是另有隱情响鹃,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布案训,位于F島的核電站买置,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏强霎。R本人自食惡果不足惜忿项,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望城舞。 院中可真熱鬧轩触,春花似錦、人聲如沸椿争。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秦踪。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間椅邓,已是汗流浹背柠逞。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留景馁,地道東北人板壮。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像合住,于是被迫代替她去往敵國和親绰精。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348