記動(dòng)態(tài)注冊(cè)廣播權(quán)限問題

最近在開發(fā)過程中遇到一個(gè)需求,就是跨進(jìn)程的廣播通信,一番嘗試之后發(fā)現(xiàn)首先好像靜態(tài)注冊(cè)廣播的方式行不通了校翔,因?yàn)?strong>在Android 8.0的改動(dòng)中,限制了大部分的隱式廣播注冊(cè)廊蜒,常見的解決方案有兩種:一種是通過intent.setComponent方法將意圖改為顯式的。另一種方法就是改為動(dòng)態(tài)注冊(cè)了溅漾。

ps:關(guān)于Android 8.0中關(guān)于廣播的改動(dòng)可以查看官方文檔Android 8.0 行為變更中的后臺(tái)執(zhí)行限制部分山叮。

跨進(jìn)程的廣播發(fā)送與接收解決了之后,我還想添加一個(gè)權(quán)限限制樟凄,讓其他程序如果碰巧發(fā)送了同樣Action的廣播后我自己注冊(cè)的接收器不會(huì)接受聘芜,其他程序注冊(cè)的接收器不會(huì)收到我自己發(fā)出的同樣Action的廣播。但是經(jīng)過一番想當(dāng)然的嘗試之后失敗了缝龄,于是再次去翻文檔,然后通過demo測(cè)試實(shí)踐了一番挂谍。這里先簡(jiǎn)單小結(jié)一下=:

  1. 簡(jiǎn)單的權(quán)限限制分為兩類叔壤,一類是帶有權(quán)限的發(fā)送,用于限制接收器的口叙,只有申請(qǐng)了相應(yīng)權(quán)限的接收器才能接收到廣播炼绘。另一類是帶有權(quán)限的接收,用于限制發(fā)送廣播的一方妄田,在發(fā)送廣播時(shí)使用sendBroadcast(Intent,String)方法發(fā)送廣播俺亮。
  2. 如果想要實(shí)現(xiàn)A應(yīng)用發(fā)送的廣播只有B應(yīng)用可以接收到驮捍,B應(yīng)用只能接收到A應(yīng)用發(fā)出的廣播(注意這里雖然兩句話表述好像一致,但是其實(shí)包含的情況是不同的)脚曾,應(yīng)該就需要在注冊(cè)廣播時(shí)通過permissionGroup以及protectionLevel等屬性去做更近一步的限制了东且,具體的實(shí)現(xiàn)這里就沒有再繼續(xù)下去了,后面有時(shí)間的話可以通過文檔permission對(duì)這兩個(gè)屬性的介紹嘗試一下本讥。

下面根據(jù)官方文檔廣播概況以及具體的Demo實(shí)際感受一下兩種通過權(quán)限限制的廣播:

帶權(quán)限的發(fā)送

這種方式可以用來限制廣播接收器珊泳,在發(fā)送廣播的一方通過sendBroadcast(Intent,String)方法發(fā)送他廣播,然后聲明了相應(yīng)權(quán)限的的一方中注冊(cè)的廣播接收器才能收到廣播拷沸。使用這種方式權(quán)限需要聲明在廣播發(fā)送方色查。

Project A -- (BroadcastTest1):

<!-- AndroidManifest.xml  -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest1">

    <!--    聲明權(quán)限 -->
    <permission android:name="com.yu.hu.permissions.BUGREPORT"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
    </application>

</manifest>
class MainActivity : AppCompatActivity() {
    companion object {
        const val TAG = "MainActivity"
        const val ACTION = "com.yu.hu.action.BUGREPPORT"
        const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = findViewById<Button>(R.id.send_btn)
        //添加button點(diǎn)擊事件
        button.setOnClickListener {
            val intent = Intent(ACTION)
            intent.putExtra("test", "test")
            Log.d(TAG, "send BroadcastReceiver with permission")
            //帶有權(quán)限的發(fā)送 接收方必須申請(qǐng)相應(yīng)權(quán)限才能正常接受到
            sendBroadcast(intent,PERMISSION)
        }
    }
}

Project B -- (BroadcastTest2):

<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest2">

    <!-- 申請(qǐng)權(quán)限 -->
    <uses-permission android:name="com.yu.hu.permissions.BUGREPORT" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
    </application>

</manifest>
class BugReportReceiver : BroadcastReceiver() {

    companion object {
        const val TAG = "BugReportReceiver"
        const val ACTION = "com.yu.hu.action.BUGREPPORT"
        const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"
    }

    override fun onReceive(context: Context?, intent: Intent?) {

        val value = intent?.getStringExtra("test")
        Log.d(TAG, "onReceive: msg = $value")
        Toast.makeText(context, "msg2 = $value", Toast.LENGTH_SHORT).show()
    }
}
class MainActivity : AppCompatActivity() {

    companion object {
        const val TAG = "MainActivity2"
        const val ACTION = "com.yu.hu.action.BUGREPPORT"
        const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val ifl = IntentFilter()
        ifl.addAction(BugReportReceiver.ACTION)
        registerReceiver(BugReportReceiver(), ifl)
    }
}

Project C -- (BroadcastTest3):

class BugReportReceiver : BroadcastReceiver() {

    companion object {
        const val TAG = "BugReportReceiver"
        const val ACTION = "com.yu.hu.action.BUGREPPORT"
        const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"
    }

    override fun onReceive(context: Context?, intent: Intent?) {=

        val value = intent?.getStringExtra("test")
        Log.d(TAG, "onReceive: msg = $value")
        Toast.makeText(context, "msg2 = $value", Toast.LENGTH_SHORT).show()
    }
}
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        registerReceiver(BugReportReceiver(), IntentFilter(BugReportReceiver.ACTION))
    }
}

點(diǎn)擊Button后輸出結(jié)果:

2020-07-10 12:51:27.155 25951-25951/com.example.broadcasttest1 D/MainActivity: send BroadcastReceiver with permission
2020-07-10 12:51:27.157 31322-31336/? W/BroadcastQueue: Permission Denial: receiving Intent { act=com.yu.hu.action.BUGREPPORT flg=0x10 (has extras) } to ProcessRecord{3b20417 25865:com.example.boradcasttest3/u0a164} (pid=25865, uid=10164) requires com.yu.hu.permissions.BUGREPORT due to sender com.example.broadcasttest1 (uid 10155)
2020-07-10 12:51:27.161 25907-25907/com.example.broadcasttest2 D/BugReportReceiver: onReceive: msg = test

可以看到只有B收到了廣播了而C沒有收到,因?yàn)?strong>B在AndroidManifest.xml中申請(qǐng)了權(quán)限撞芍,而C沒有秧了,所以報(bào)了Permission Denial的錯(cuò)誤。在C中也申請(qǐng)了權(quán)限后就同樣能接收到廣播了序无。

帶權(quán)限的接收

這種方式可以用來限制發(fā)送廣播的一方验毡,只有申請(qǐng)了相應(yīng)的權(quán)限才能成功發(fā)送廣播。使用這種方式權(quán)限需要聲明在廣播接收器的注冊(cè)方愉镰。
Project A -- (BroadcastTest1): - 申請(qǐng)權(quán)限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest1">

    <uses-permission android:name="com.test.permission.receiver"/>
    ...
</manifest>
class MainActivity : AppCompatActivity() {
    companion object {
        const val TAG = "MainActivity"
        const val ACTION = "com.yu.hu.action.BUGREPPORT"
        const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = findViewById<Button>(R.id.send_btn)
        button.setOnClickListener {
            val intent = Intent(ACTION)
            intent.putExtra("test", "test")
            Log.d(TAG, "send Broadcast with permission")
            sendBroadcast(intent)
        }
    }
}

Project B -- (BroadcastTest2): - 不申請(qǐng)權(quán)限

class MainActivity : AppCompatActivity() {

    companion object {
        const val TAG = "MainActivity2"
        const val ACTION = "com.yu.hu.action.BUGREPPORT"
        const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = findViewById<Button>(R.id.send_btn)
        button.setOnClickListener {
            val intent = Intent(ACTION)
            intent.putExtra("test", "test")
            Log.d(TAG, "send Broadcast without permission")
            //不申請(qǐng)權(quán)限發(fā)送
            sendBroadcast(intent)
        }
    }
}

Project C -- (BroadcastTest3): - 聲明權(quán)限并在注冊(cè)時(shí)添加權(quán)限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.boradcasttest3">

    <permission android:name="com.test.permission.receiver"/>
    ...

</manifest>
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        registerReceiver(BugReportReceiver(), IntentFilter(BugReportReceiver.ACTION), "com.test.permission.receiver", null)
    }
}

A中發(fā)送廣播:

2020-07-10 14:07:36.187 12843-12843/com.example.broadcasttest1 D/MainActivity: send Broadcast with permission
2020-07-10 14:07:36.191 12600-12600/com.example.boradcasttest3 D/BugReportReceiver: onReceive2: msg = test

成功發(fā)送也成功接收處理米罚。下面是在B中發(fā)送廣播的日志:

2020-07-10 14:08:04.368 13003-13003/com.example.broadcasttest2 D/MainActivity2: send Broadcast without permission
2020-07-10 14:08:04.370 31322-31336/? W/BroadcastQueue: Permission Denial: broadcasting Intent { act=com.yu.hu.action.BUGREPPORT flg=0x10 (has extras) } from com.example.broadcasttest2 (pid=13003, uid=10162) requires com.test.permission.receiver due to registered receiver BroadcastFilter{37dbe8b u0 ReceiverList{7706c5a 12600 com.example.boradcasttest3/10164/u0 remote:8530405}}

發(fā)送之后報(bào)了Permission Denial,所以接收器沒有接收到這條廣播丈探。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末录择,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子碗降,更是在濱河造成了極大的恐慌隘竭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讼渊,死亡現(xiàn)場(chǎng)離奇詭異动看,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)爪幻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門菱皆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挨稿,你說我怎么就攤上這事仇轻。” “怎么了奶甘?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵篷店,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我臭家,道長(zhǎng)疲陕,這世上最難降的妖魔是什么方淤? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蹄殃,結(jié)果婚禮上携茂,老公的妹妹穿的比我還像新娘。我一直安慰自己窃爷,他們只是感情好邑蒋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著按厘,像睡著了一般医吊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逮京,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天卿堂,我揣著相機(jī)與錄音,去河邊找鬼懒棉。 笑死草描,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的策严。 我是一名探鬼主播穗慕,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼妻导!你這毒婦竟也來了逛绵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤倔韭,失蹤者是張志新(化名)和其女友劉穎术浪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寿酌,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胰苏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了醇疼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硕并。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秧荆,靈堂內(nèi)的尸體忽然破棺而出鲤孵,到底是詐尸還是另有隱情,我是刑警寧澤辰如,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站贵试,受9級(jí)特大地震影響琉兜,放射性物質(zhì)發(fā)生泄漏凯正。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一豌蟋、第九天 我趴在偏房一處隱蔽的房頂上張望廊散。 院中可真熱鬧,春花似錦梧疲、人聲如沸允睹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缭受。三九已至,卻和暖如春该互,著一層夾襖步出監(jiān)牢的瞬間米者,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工宇智, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔓搞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓随橘,卻偏偏與公主長(zhǎng)得像喂分,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子机蔗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355