Android广播的学习和使用
1.引子
最近開發碰到一個需求,客戶的設備是自助售貨機,他們要求應用靜默安裝后能夠啟動,因為派人去現場一個個點擊打開應用不現實。作為論壇復制粘貼工程師,碰到這個需求第一時間就是去網上搜索,看看這種需求有什么解決方案,網上文章很多,都說用靜態廣播,但我復制他們的代碼一直沒效果,反復排查哪里漏復制了,結果都不是,而是因為,這里先賣個關子,先學習一下廣播,不然復制粘貼后還是啥都不懂。
2.廣播定義
Android里的廣播,和我們日常里的廣播是相似的,都是用于消息的傳遞,但消息的傳遞不是一對一的傳遞,而是多對多的傳遞,這種模式稱之為發布-訂閱模式,發布者有很多,每個發布者都可以廣播,不關心具體訂閱者都是誰,訂閱者有很多,每個訂閱者只關心自己感興趣的廣播。舉個例子,校園廣播站每到放學時間打開廣播,播放音樂、校園新聞等,這些不是發給特定的人,而是面向整個學校的師生,同樣,聽廣播的師生,只挑感興趣的廣播注意收聽,其他的不管,同時也不關心是誰在播放廣播。
3.廣播模型
發布-訂閱模式有兩個角色,分別是廣播發布者和廣播接收者,但在Android系統中,還有一個消息中心(Activity Manager Service)用于廣播發分發。
不同的廣播發布者往消息中心添加消息,眾多的廣播接收者需要先跟消息中心注冊,告訴消息中心當有特點類型廣播消息到達時,就通知它,這個過程是異步的,這樣廣播發布者和廣播接收者是解耦的,不需要知道對方的存在,不需要雙方同時在線。
4.廣播的使用
4.1 廣播的發送
廣播發布者有系統也有應用,如果是系統,由系統自己發送廣播,系統時刻在關注著系統內發生的各類事件,它就像一個愛八卦,當檢測到下表總結的事件發生時,就將這些事件廣播出去,例如系統啟動完成,它會通過廣播形式告訴大家我啟動完成啦,當有應用安裝時,它也同樣發一個全局的廣播,有新的應用入住啦。
| 監聽網絡變化 | android.net.conn.CONNECTIVITY_CHANGE |
| 關閉或打開飛行模式 | Intent.ACTION_AIRPLANE_MODE_CHANGED |
| 充電時或電量發生變化 | Intent.ACTION_BATTERY_CHANGED |
| 電池電量低 | Intent.ACTION_BATTERY_LOW |
| 電池電量充足(即從電量低變化到飽滿時會發出廣播 | Intent.ACTION_BATTERY_OKAY |
| 系統啟動完成后(僅廣播一次) | Intent.ACTION_BOOT_COMPLETED |
| 按下照相時的拍照按鍵(硬件按鍵)時 | Intent.ACTION_CAMERA_BUTTON |
| 屏幕鎖屏 | Intent.ACTION_CLOSE_SYSTEM_DIALOGS |
| 設備當前設置被改變時(界面語言、設備方向等) | Intent.ACTION_CONFIGURATION_CHANGED |
| 插入耳機時 | Intent.ACTION_HEADSET_PLUG |
| 未正確移除SD卡但已取出來時(正確移除方法:設置–SD卡和設備內存–卸載SD卡) | |
| 插入外部儲存裝置(如SD卡) | Intent.ACTION_MEDIA_CHECKING |
| 成功安裝APK | Intent.ACTION_PACKAGE_ADDED |
| 成功刪除APK | Intent.ACTION_PACKAGE_REMOVED |
| 重啟設備 | Intent.ACTION_REBOOT |
| 屏幕被關閉 | Intent.ACTION_SCREEN_OFF |
| 屏幕被打開 | Intent.ACTION_SCREEN_ON |
| 關閉系統時 | Intent.ACTION_SHUTDOWN |
| 重啟設備 | Intent.ACTION_REBOOT |
如果廣播發布者是應用,則通過Intent發送自定義的廣播,如下是發送一個自定義的廣播
Intent intent = new Intent();intent.setAction("com.example.broadcast.MY_NOTIFICATION");intent.putExtra("data","Notice me");sendBroadcast(intent);4.2 廣播的接收
和廣播發送不同,廣播接收稍微復雜一點,因為廣播接收需要接收者先跟消息中心注冊,注冊又分為兩大類,分別是靜態注冊和動態注冊。
4.2.1 靜態注冊
A. 定義一個廣播類
繼承BroadcastReceiver定義一個廣播類,重寫onRecevie回調方法,onReceieve回調方法中是我們想要廣播接收器收到廣播之后需要處理的操作
B. 在AndroidManifest.xml里通過標簽聲明上一步定義的廣播類
<receiver android:name=".mBroadcastReceiver" >//用于應用安裝發出的廣播<intent-filter><action android:name="android.intent.action.PACKAGE_ADDED" /> <data android:scheme="package" /> </intent-filter> </receiver>這就完成了靜態注冊,其中,用于設置我們感興趣的廣播。需要注意的是,這段代碼在Android8.0及以上并不能正常接收到應用安裝的廣播!!運行代碼會報Background execution not allowed-PACKAGE_ADDED的錯誤,因為從 Android 8.0(API 級別 26)開始,出于限制后臺啟動的作用,系統對清單聲明的接收器施加了額外的限制,大多數隱式廣播(沒有明確針對您的應用的廣播)不能通過靜態注冊接收,靜態注冊仍可以接收的我們應用自定義的指定包名的廣播,以及豁免的廣播(見豁免廣播類型)
不過,雖然靜態注冊不能接收到這些廣播,但動態注冊不受影響,因此為了正常接收廣播,可通過動態注冊的方式。
4.2.2 動態注冊
所謂的動態注冊,是指在代碼中調用Context.registerReceiver()方法,整體步驟如下:
需要注意的是,動態注冊的廣播接收器一定要注銷,在onDestroy方法中調用unregisterReceiver(mbroadcastReceiver)完成注銷,否則會報內存泄露錯誤。
5.總結
首先回答引子里的問題,為什么靜態注冊無法接收應用安裝廣播,因為Android 8.0對這類廣播做了限制。廣播的使用算是四大組件里使用較簡單的一種,當時復制粘貼其他博客寫的代碼后總是無法正常接收廣播時,不相信使用如此簡單,一直懷疑是不是遺漏了什么,當學習一遍廣播時還真是如此,特別是靜態注冊,不過Android 8.0以后靜態注冊也不好使,被限制了很多。
總結
以上是生活随笔為你收集整理的Android广播的学习和使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android权限申请的学习实践
- 下一篇: 小甲鱼c++学习视频之运算符重载