廣播接收者(BroadcastReceiver)
1.定義廣播接受者
靜態(tài)注冊(cè)廣播
-
定義類繼承BroadcastReceiver,重寫onReceive方法
public class BroadCastReceiverDemo extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"廣播接受者--Boot Complete.",Toast.LENGTH_LONG).show(); } }
-
清單文件中聲明<receiver>,需要在其中配置<intent-filter>指定接收廣播的動(dòng)作
<!-- 開機(jī)廣播接受者 --> <receiver android:name=".BroadCastReceiverDemo"> <intent-filter> <!-- 注冊(cè)開機(jī)廣播地址--> <action android:name="android.intent.action.BOOT_COMPLETED"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
-
當(dāng)接收到匹配廣播之后就會(huì)執(zhí)行onReceive方法
@Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"廣播接受者----Boot Complete.",Toast.LENGTH_LONG).show(); }
-
BroadcastReceiver的優(yōu)先級(jí)
<!-- 開機(jī)廣播接受者 --> <receiver android:name=".BroadCastReceiverDemo"> <intent-filter android:priority="2147483647"> <!-- 注冊(cè)開機(jī)廣播地址--> <action android:name="android.intent.action.BOOT_COMPLETED"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
2147483647是最高優(yōu)先級(jí),默認(rèn)是0.
動(dòng)態(tài)注冊(cè)廣播
-
BroadcastReceiver除了在清單文件中聲明,也可以在代碼中聲明,使用registerReceiver方法注冊(cè)Receiver
public class MainActivity extends Activity { private CodeReceiver receiver; private IntentFilter filter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); filter = new IntentFilter("android.intent.action.SCREEN_ON"); filter.setPriority(100); //優(yōu)先級(jí) receiver = new CodeReceiver(); registerReceiver(receiver, filter); // Activity創(chuàng)建時(shí)注冊(cè)接收者 } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); // Activity退出時(shí)注銷接收者 } }
2.發(fā)送廣播
無序廣播
- 使用sendBroadcast方法發(fā)送
- 被所有廣播接收者接收,無序,不可中斷
- 廣播時(shí)可設(shè)置接收者權(quán)限,僅當(dāng)接收者含有權(quán)限才能接收
- 接收者的<receiver>也可設(shè)置發(fā)送方權(quán)限,只接收含有權(quán)限應(yīng)用的廣播
無序廣播發(fā)送方法
void sendBroadcast (Intent intent, String receiverPermission)
參數(shù):
intent The Intent to broadcast; 傳給接收者的意圖 all receivers matching this Intent will receive the broadcast.所有匹配的廣播接受者都回收到這一意圖
receiverPermission (optional)可選的 String naming a permission that a receiver must hold in order to receive your broadcast.一個(gè)接收者必須擁有的權(quán)限 If null, no permission is required. 如果為null,則沒有要求
示例:
sendBroadcast(intent, null);
有序廣播
- 使用sendOrderedBroadcast方法發(fā)送
- 接收者可以在<intent-filter>中定義android:priority定義優(yōu)先級(jí),數(shù)字越大優(yōu)先級(jí)越高
- 被各個(gè)廣播接收者逐個(gè)接收,中途可以中斷或者添加數(shù)據(jù)
abortBroadcast()
getResultExtras(true).putString("data", "新增數(shù)據(jù)");
<receiver android:name="com.top.myreceiver.MyReceiver1" >
<intent-filter android:priority="1000">
<action android:name="com.top.mybroadcast.xxx" />
</intent-filter>
</receiver>
<receiver android:name="com.top.myreceiver.MyReceiver2" >
<intent-filter android:priority="500">
<action android:name="com.top.mybroadcast.xxx"/>
</intent-filter>
</receiver>
<receiver android:name="com.top.myreceiver.MyReceiver3" >
<intent-filter android:priority="100">
<action android:name="com.top.mybroadcast.xxx" />
</intent-filter>
</receiver>
- 有序廣播發(fā)送方法
void sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
參數(shù)
intent* The Intent to broadcast; 傳給接收者的意圖 all receivers matching this Intent will receive the broadcast.所有匹配的廣播接受者都回收到這一意圖
receiverPermission (optional)可選的 String naming a permission that a receiver must hold in order to receive your broadcast.一個(gè)接收者必須擁有的權(quán)限 If null, no permission is required. 如果為null,則沒有要求
resultReceiver Your own BroadcastReceiver to treat as the final receiver of the broadcast. 指定一的廣播的最終接受者(必須執(zhí)行的)
scheduler A custom Handler with which to schedule the resultReceiver callback;指定你的接收者回掉的handler; if null it will be scheduled in the Context's main thread. 如果為空,則默認(rèn)為主線程
initialCode An initial value for the result code.初始的結(jié)果碼 Often Activity.RESULT_OK. 通常設(shè)置
initialData An initial value for the result data.初始的結(jié)果數(shù)據(jù) Often null. 通常為null
initialExtras An initial value for the result extras.初始化附加信息bundle; Often null通常為null
示例
Intent intent = new Intent("com.top.broadcast.TEST"); // 創(chuàng)建意圖對(duì)象, 設(shè)置廣播的動(dòng)作
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); // 廣播是否啟動(dòng)那些沒有啟動(dòng)過的應(yīng)用
intent.putExtra("data", "最初的數(shù)據(jù)!!!"); // 這里的數(shù)據(jù)不會(huì)被修改
Bundle bundle = new Bundle();
bundle.putString("name", "張三");
sendOrderedBroadcast(intent, "com.top.permission.BROADCAST", new ResultReciever(), null, 1, "MainActivity", bundle);
短信黑名單
- Android系統(tǒng)在收到短信的時(shí)候會(huì)發(fā)送一條有序廣播,我們?nèi)绻x一個(gè)接收者接收這個(gè)廣播,就可以得到短信內(nèi)容,也可以攔截短信
- 定義廣播接收者接收廣播android.provider.Telephony.SMS_RECEIVED
- 在onReceive方法內(nèi)部調(diào)用Intent的getExtras()再調(diào)用get()獲取其中pdus字段,得到一個(gè)Object[],其中每一個(gè)元素都是一個(gè)byte[]
- 通過SmsMessage類的createFromPdu方法創(chuàng)建SmsMessage對(duì)象
- 從SmsMessage對(duì)象中即可獲取發(fā)送者號(hào)碼、短信內(nèi)容、發(fā)送時(shí)間等信息
- 需要接收短信權(quán)限:<uses-permission android:name="android.permission.RECEIVE_SMS"/>
- Android系統(tǒng)中收到短信的通知是一個(gè)有序通知,我們?nèi)缧钄r截垃圾短信,可以配置較高的priority,收到信息進(jìn)行判斷是否abortBroadcast()
自動(dòng)IP撥號(hào)
- 定義廣播接收者接收 android.intent.action.NEW_OUTGOING_CALL
- 需要權(quán)限 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
- 在onReceive方法中使用getResultData() 和 setResultData() 方法獲取和設(shè)置電話號(hào)碼
廣播接收者生命周期 Broadcast receiver lifecycle
- 廣播接收者的生命周期是非常短暫的,在接收到廣播的時(shí)候創(chuàng)建,onReceive()方法結(jié)束之后銷毀。當(dāng)廣播消息抵達(dá)接收器時(shí),Android調(diào)用它的onReceive()方法并將包含消息的Intent對(duì)象傳遞給它。廣播接收器僅在它執(zhí)行這個(gè)方法時(shí)處于活躍狀態(tài)。當(dāng)onReceive()返回后,它即為失活狀態(tài)。
擁有一個(gè)活躍狀態(tài)的廣播接收器的進(jìn)程被保護(hù)起來而不會(huì)被殺死。但僅擁有失活狀態(tài)組件的進(jìn)程則會(huì)在其它進(jìn)程需要它所占有的內(nèi)存的時(shí)候隨時(shí)被殺掉。
//廣播接收器只有一個(gè)回調(diào)方法:void onReceive(Context curContext, Intent broadcastMsg)
- 廣播接收者是在主線程中執(zhí)線的,廣播接收者中不要做一些耗時(shí)的工作,否則會(huì)彈出Application No Response錯(cuò)誤對(duì)話框
- 最好也不要在廣播接收者中創(chuàng)建子線程做耗時(shí)的工作,因?yàn)閺V播接收者被銷毀后進(jìn)程就成為了空進(jìn)程,很容易被系統(tǒng)殺掉
- 耗時(shí)的較長(zhǎng)的工作最好放在服務(wù)中完成