Android四大組件 BroadcastReceiver

廣播2種注冊方式:靜態(tài)注冊和動態(tài)注冊

  • 靜態(tài)注冊:在AndroidManifest.xml文件中進(jìn)行注冊,當(dāng)App退出后,Receiver仍然可以接收到廣播并且進(jìn)行相應(yīng)的處理宏侍。

API 級別 26 或更高級別的平臺版本為目標(biāo),則不能使用清單為隱式廣播(沒有明確針對您的應(yīng)用的廣播)聲明接收器,但一些不受此限制的隱式廣播除外洼怔。在大多數(shù)情況下,您可以使用調(diào)度作業(yè)來代替左驾。

    <receiver android:name=".MyBroadcastReceiver"  android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
        </intent-filter>
    </receiver>
    
    private const val TAG = "MyBroadcastReceiver"

    class MyBroadcastReceiver : BroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {
            StringBuilder().apply {
                append("Action: ${intent.action}\n")
                append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
                toString().also { log ->
                    Log.d(TAG, log)
                    Toast.makeText(context, log, Toast.LENGTH_LONG).show()
                }
            }
        }
    }
  • 動態(tài)注冊:在代碼中動態(tài)注冊镣隶,當(dāng)App退出后,也就沒辦法再接受廣播了
    val br: BroadcastReceiver = MyBroadcastReceiver()
    val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
        addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED)
    }
    registerReceiver(br, filter)
//要注冊本地廣播诡右,請調(diào)用 `LocalBroadcastManager.registerReceiver(BroadcastReceiver, IntentFilter)`

停止接收廣播安岂,請調(diào)用 unregisterReceiver(android.content.BroadcastReceiver)。當(dāng)您不再需要接收器或上下文不再有效時帆吻,請務(wù)必注銷接收器域那。

發(fā)送廣播三種方式

  • sendOrderedBroadcast(Intent, String) 方法一次向一個接收器發(fā)送廣播。當(dāng)接收器逐個順序執(zhí)行時猜煮,接收器可以向下傳遞結(jié)果次员,也可以完全中止廣播,使其不再傳遞給其他接收器王带。接收器的運(yùn)行順序可以通過匹配的 intent-filter 的 android:priority 屬性來控制淑蔚;具有相同優(yōu)先級的接收器將按隨機(jī)順序運(yùn)行。
  • sendBroadcast(Intent) 方法會按隨機(jī)的順序向所有接收器發(fā)送廣播愕撰。這稱為常規(guī)廣播刹衫。這種方法效率更高醋寝,但也意味著接收器無法從其他接收器讀取結(jié)果,無法傳遞從廣播中收到的數(shù)據(jù)带迟,也無法中止廣播音羞。
  • LocalBroadcastManager.sendBroadcast 方法會將廣播發(fā)送給與發(fā)送器位于同一應(yīng)用中的接收器。如果您不需要跨應(yīng)用發(fā)送廣播仓犬,請使用本地廣播嗅绰。這種實(shí)現(xiàn)方法的效率更高(無需進(jìn)行進(jìn)程間通信),而且您無需擔(dān)心其他應(yīng)用在收發(fā)您的廣播時帶來的任何安全問題婶肩。

發(fā)送廣播限制及API更改

隨著 Android 平臺的發(fā)展办陷,它會不定期地更改系統(tǒng)廣播的行為方式。如果您的應(yīng)用以 Android 7.0(API 級別 24)或更高版本為目標(biāo)平臺律歼,或者安裝在搭載 Android 7.0 或更高版本的設(shè)備上民镜,請注意以下更改。

#### Android 9

從 Android 9(API 級別 28)開始险毁,[`NETWORK_STATE_CHANGED_ACTION`](https://developer.android.com/reference/android/net/wifi/WifiManager?hl=zh-cn#NETWORK_STATE_CHANGED_ACTION) 廣播不再接收有關(guān)用戶位置或個人身份數(shù)據(jù)的信息制圈。

此外,如果您的應(yīng)用安裝在搭載 Android 9 或更高版本的設(shè)備上畔况,則通過 WLAN 接收的系統(tǒng)廣播不包含 SSID鲸鹦、BSSID、連接信息或掃描結(jié)果跷跪。要獲取這些信息馋嗜,請調(diào)用 [`getConnectionInfo()`](https://developer.android.com/reference/android/net/wifi/WifiManager?hl=zh-cn#getConnectionInfo())。

#### Android 8

從 Android 8.0(API 級別 26)開始吵瞻,系統(tǒng)對清單聲明的接收器施加了額外的限制葛菇。

如果您的應(yīng)用以 Android 8.0 或更高版本為目標(biāo)平臺,那么對于大多數(shù)隱式廣播(沒有明確針對您的應(yīng)用的廣播)橡羞,您不能使用清單來聲明接收器眯停。當(dāng)用戶正在活躍地使用您的應(yīng)用時,您仍可使用[上下文注冊的接收器](https://developer.android.com/guide/components/broadcasts?hl=zh-cn#context-registered-recievers)卿泽。

#### Android 7

Android 7.0(API 級別 24)及更高版本不發(fā)送以下系統(tǒng)廣播:

*   `[ACTION_NEW_PICTURE](https://developer.android.com/reference/android/hardware/Camera?hl=zh-cn#ACTION_NEW_PICTURE)`
*   `[ACTION_NEW_VIDEO](https://developer.android.com/reference/android/hardware/Camera?hl=zh-cn#ACTION_NEW_VIDEO)`

此外莺债,以 Android 7.0 及更高版本為目標(biāo)平臺的應(yīng)用必須使用 `[registerReceiver(BroadcastReceiver, IntentFilter)](https://developer.android.com/reference/android/content/Context?hl=zh-cn#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter))` 注冊 `[CONNECTIVITY_ACTION](https://developer.android.com/reference/android/net/ConnectivityManager?hl=zh-cn#CONNECTIVITY_ACTION)` 廣播。無法在清單中聲明接收器签夭。

  • 通過權(quán)限限制廣播
    帶權(quán)限的發(fā)送齐邦,當(dāng)您調(diào)用 sendBroadcast(Intent, String) 或 sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) 時,可以指定權(quán)限參數(shù)第租。接收器若要接收此廣播侄旬,則必須通過其清單中的 <uses-permission style="box-sizing: inherit;">標(biāo)記請求該權(quán)限(如果存在危險(xiǎn),則會被授予該權(quán)限)煌妈。
發(fā)送:
    sendBroadcast(Intent("com.example.NOTIFY"), Manifest.permission.SEND_SMS)

接收權(quán)限:
<uses-permission android:name="android.permission.SEND_SMS"/>

帶權(quán)限接收,如果您在注冊廣播接收器時指定了權(quán)限參數(shù)(通過 registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) 或清單中的 <receiver>,則廣播方必須通過其清單中的 <uses-permission> 標(biāo)記請求該權(quán)限(如果存在危險(xiǎn)璧诵,則會被授予該權(quán)限)汰蜘,才能向該接收器發(fā)送 Intent。

接收:
var filter = IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)
registerReceiver(receiver, filter, Manifest.permission.SEND_SMS, null )

發(fā)送:
<uses-permission android:name="android.permission.SEND_SMS"/>    

廣播最佳做法建議

  • 優(yōu)先只用應(yīng)用內(nèi)廣播
  • 優(yōu)先使用動態(tài)注冊廣播
  • 廣播命名帶包名防止同名廣播
  • onReceive()主線程執(zhí)行之宿,不要在主線程執(zhí)行耗時任務(wù)
  • 廣播可作為跨應(yīng)用和普通用戶流之外的消息傳遞系統(tǒng)族操。但是,您必須小心比被,不要濫用在后臺響應(yīng)廣播和運(yùn)行作業(yè)的機(jī)會色难,因?yàn)檫@會導(dǎo)致系統(tǒng)變慢。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末等缀,一起剝皮案震驚了整個濱河市枷莉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尺迂,老刑警劉巖笤妙,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異噪裕,居然都是意外死亡蹲盘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門膳音,熙熙樓的掌柜王于貴愁眉苦臉地迎上來召衔,“玉大人,你說我怎么就攤上這事祭陷〔粤荩” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵颗胡,是天一觀的道長毫深。 經(jīng)常有香客問我,道長毒姨,這世上最難降的妖魔是什么哑蔫? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮弧呐,結(jié)果婚禮上闸迷,老公的妹妹穿的比我還像新娘。我一直安慰自己俘枫,他們只是感情好腥沽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鸠蚪,像睡著了一般今阳。 火紅的嫁衣襯著肌膚如雪师溅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天盾舌,我揣著相機(jī)與錄音墓臭,去河邊找鬼。 笑死妖谴,一個胖子當(dāng)著我的面吹牛窿锉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播膝舅,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嗡载,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了仍稀?” 一聲冷哼從身側(cè)響起洼滚,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎琳轿,沒想到半個月后判沟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡崭篡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年挪哄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琉闪。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡迹炼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出颠毙,到底是詐尸還是另有隱情斯入,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布蛀蜜,位于F島的核電站刻两,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏滴某。R本人自食惡果不足惜磅摹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望霎奢。 院中可真熱鬧户誓,春花似錦、人聲如沸幕侠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晤硕。三九已至悼潭,卻和暖如春庇忌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背女责。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工漆枚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抵知。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像软族,于是被迫代替她去往敵國和親刷喜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容