四大元件之BroadcastReceiver(二)-使用許可權和常用的系統廣播
更新時間 | 修改意見 |
---|---|
2016-08-02 | 陳敏 |
第4節 Broadcast的使用許可權
為廣播設定許可權要考慮兩方面的問題。
- 作為廣播的傳送者,希望限制廣播的接收者,只讓特定的應用元件接收到發出的廣播;
- 作為廣播的接收者,不希望任何元件都能模仿它關心的廣播,因此希望在接受廣播的時候能檢查一下這條廣播的傳送者是否具有傳送這條廣播的資格;
無論是上面哪種情況,解決方法都是一樣的:為傳送者和接收者都設定一個相同的許可權,只有它們的許可權匹配上了,廣播機制才能產生效果。
4.1 限制接收者
假設元件A要釋出廣播,
在
AndroidManifest.xml
<application/>
同級的位置,對外宣告使用許可權,表示這個應用釋出了一個叫做com.anddle.receiver.receivebroadcast
的許可權,<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <permission android:name="com.anddle.receiver.receivebroadcast" android:label="receiver permission" android:protectionLevel
在元件向整個系統釋出廣播的時候,就採用,
//前一個引數是廣播的名稱,後一個引數是廣播許可權的名稱 sendBroadcast("custom.action.mybroadcast","com.anddle.receiver.receivebroadcast");
這裡的廣播許可權
com.anddle.receiver.receivebroadcast
,就是AndroidManifest.xml
中宣告的許可權。
當接收者
要接收這種廣播的時候,
接受者
AndroidManifest.xml
當中靜態的定義好接收機
對應的receiver
,或者在程式碼當中動態的定義好接收機
對應的receiver
;在它的
AndroidManifest.xml
當中,宣告要使用的許可權,<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <!--宣告要使用的許可權--> <users-permission android:name = "com.anddle.receiver.receivebroadcast"/> <application ......> <!--假設採用的是靜態定義的接收機--> <receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="custom.action.mybroadcast"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver> </application> </manifest>
4.2 限制傳送者
假設接收者1
要設定許可權,只接收特定傳送者
發來的廣播,
在
AndroidManifest.xml
檔案中,對要設定許可權的Broadcast Receiver
設定上android:permission
屬性,該屬性值可以任意指定一個字串。通常使用程式的包名作為其中的一部分,這樣可以避免和其他應用中的許可權宣告衝突。例如com.anddle.receiver.sendbroadcast
,<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true" android:permission="com.anddle.receiver.sendbroadcast" />
在
AndroidManifest.xml
檔案中,與<application/>
同級的位置,對外宣告前面使用的標籤,表示這個應用釋出了一個叫做com.anddle.receiveraccess
的許可權,<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <permission android:name="com.anddle.receiver.sendbroadcast" android:label="receiver permission" android:protectionLevel="normal" /> <application ....../> </manifest>
其中
android:name
屬性的值,就是<receiver/>
標籤中設定的android:permission
的值。
傳送者B要傳送相應的廣播,就要
在B的
AndroidManifest.xml
中加入許可權的使用,<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.anddle.calculator"> <uses-permission android:name="com.anddle.receiver.sendbroadcast"/> <application ....../> </manifest>
其中,
<uses-permission/>
標籤中設定的android:name
的值,就是應用A中對外宣告的那個Broadcast Receiver
的許可權值。使用程式碼傳送廣播,
Intent i = new Intent("custom.action.mybroadcast"); sendBroadcast(i);
4.3 接收其它應用的廣播
在應用的AndroidManifest.xml
檔案中,Broadcast Receiver
具有android:exported
屬性,
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true"></receiver>
android:exported
屬性設定成true
:可以接收其他應用發來的廣播;android:exported
屬性設定成false
:不能接收其他應用發來的廣播;
所以當兩個不同的應用之間需要傳送和接收廣播的時候,需要把這個屬性設定成true
。
/*******************************************************************/
* 版權宣告
* 本教程只在CSDN和安豆網釋出,其他網站出現本教程均屬侵權。
/*******************************************************************/
第5節 系統的廣播
系統提供了很多現成的廣播,開發者可以根據自己應用的需要,關注某些特定的廣播。這裡介紹幾種使用頻率最高的廣播。
5.1 開機完成
有的時候,應用希望在開機完成之後,啟動一個在後臺執行的Service
。例如我們常用的微信應用,開機後會啟動一個Service
和網路相連,如果有訊息來,就通知我們有朋友發訊息來了。
但是系統剛啟動,使用者沒有主動開啟微信,那麼這個微信的Service
是不會執行起來的。這時候,就可以使用Broadcast Receiver
了,讓它關注一個叫做android.intent.action.BOOT_COMPLETED
的廣播,
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.intent.action.BOOT_COMPLETED" />
這樣,等開機完成後,系統發出android.intent.action.BOOT_COMPLETED
廣播後,MyReceiver
就可以收到這條廣播,進行自己的處理-例如執行一個Service
了。
使用這條廣播有個很重要的地方需要注意,從Android 4.0的系統開始,安裝了這個應用以後,使用者必須手動啟動一次該應用(執行該應用的Activity),這樣重啟裝置之後,就能收到android.intent.action.BOOT_COMPLETED
廣播了。
5.2 時間變化
如果我們很關心時間的變化,例如要實現一個時鐘,每一秒的變化,時間設定改變,時區變化都將是關心的內容。
所以,可以建立動態的接收機
監聽3種廣播,
Intent.ACTION_TIME_TICK
;Intent.ACTION_TIME_CHANGED
Intent.ACTION_TIMEZONE_CHANGED
final IntentFilter filter = new IntentFilter();
//監聽每一秒的變化
filter.addAction(Intent.ACTION_TIME_TICK);
//監聽時間設定的改變
filter.addAction(Intent.ACTION_TIME_CHANGED);
//監聽時區的改變
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(receiver, filter);
同時將接收機
定義成,
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) {
//每一秒發生變化
}
else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
//時間發生變化
}
else if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
//時區發生變化
}
}
};
/*******************************************************************/
* 版權宣告
* 本教程只在CSDN和安豆網釋出,其他網站出現本教程均屬侵權。
*另外,我們還推出了Arduino智慧硬體相關的教程,您可以在我們的網店跟我學Arduino程式設計中購買相關硬體。同時也感謝大家對我們這些碼農的支援。
*最後再次感謝各位讀者對安豆
的支援,謝謝:)
/*******************************************************************/