Android系統(tǒng)四大組件播聪,Activity(活動)提供界面負責用戶交互,Service(服務)沒有用戶界面主要是在后臺執(zhí)行任務布隔,Content Provider(內(nèi)容提供者)用于不同應用間數(shù)據(jù)共享离陶,今天介紹的是最后一個,BroadcastReceiver(廣播接收器)衅檀。
一招刨、 BroadcastReceiver是什么
二、 BroadcastReceiver基本用法
三哀军、 BroadcastReceiver例子
四沉眶、 BroadcastReceiver總結(jié)
一打却、 BroadcastReceiver是什么
簡單來說,BroadcastReceiver廣播接收器就是一個全局的監(jiān)聽器谎倔,它可以監(jiān)聽用戶自己開發(fā)的程序和系統(tǒng)的發(fā)出的廣播消息柳击。具體來說,我們的手機在使用過程中肯定會經(jīng)歷很多的狀態(tài)片习,比如電池電量低捌肴、系統(tǒng)的時間變化、系統(tǒng)收到短信等等藕咏,這些狀態(tài)發(fā)生時系統(tǒng)會對外發(fā)送標準廣播状知,我們通過繼承BroadcastReceiver新建自己的廣播接收器來監(jiān)聽這些標準廣播,即可在特定的時候完成指定的操作侈离。
二试幽、 BroadcastReceiver基本用法
這里先假設我們是自己要發(fā)送條廣播,那么我們首先要做的是創(chuàng)建Intent對象卦碾,在Intent里使用setAction方法來設置通知的標識铺坞,用以區(qū)分廣播,同時可以在Intent里攜帶數(shù)據(jù)洲胖,最后調(diào)用方法sendBroadcast來發(fā)送廣播济榨。
1.發(fā)送廣播
下面的代碼展示了發(fā)送廣播,代碼的邏輯就是點擊按鈕時發(fā)送一條廣播绿映。
public class BroadcastActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_bc);
//點擊按鈕時
Button btnSendBC = (Button) findViewById(R.id.btn_send_bc);
btnSendBC.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//實例化Intent
Intent mIntent = new Intent();
//設置標識
mIntent.setAction("com.jackaltsc.android.actiontest");
//攜帶數(shù)據(jù)
mIntent.putExtra("msg", "自定義的廣播消息");
//開始發(fā)送
sendBroadcast(mIntent);
}
});
}
}
2.接收廣播
為了接收到廣播擒滑,必須新建繼承BroadcastReceiver的子類,在里面實現(xiàn)onReceive方法來處理邏輯叉弦。
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("---bbb---", "接收到廣播內(nèi)容為:" + intent.getStringExtra("msg"));
}
}
3.注冊廣播
我們有廣播發(fā)送丐一,有廣播接收,那么怎么把兩者關聯(lián)起來呢淹冰?這時库车,就需要在清單文件里對接收器進行注冊。
<!--接收器-->
<receiver android:name=".receiver.MyReceiver">
<intent-filter>
<action android:name="com.jackaltsc.android.actiontest"/>
</intent-filter>
</receiver>
可以看到樱拴,我們把接收器和發(fā)送廣播時的標識關聯(lián)了起來柠衍,這樣廣播接收器就可以接收到通知了。
輸出結(jié)果如下:
補充一點晶乔,我們在第三步是在清單文件里注冊廣播的珍坊,這里還有另外一種方法是在代碼里設置。我們修改之前的Activity里的代碼正罢,同時刪除掉清單文件里的Receiver注冊的部分代碼阵漏,同樣可以看到結(jié)果。
public class BroadcastActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_bc);
//點擊按鈕時
Button btnSendBC = (Button) findViewById(R.id.btn_send_bc);
btnSendBC.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//過濾器
IntentFilter filter = new IntentFilter("com.jackaltsc.android.actiontest");
//實例化
MyReceiver myReceiver = new MyReceiver();
//注冊接收器
registerReceiver(myReceiver, filter);
//實例化Intent
Intent mIntent = new Intent();
//設置標識
mIntent.setAction("com.jackaltsc.android.actiontest");
//攜帶數(shù)據(jù)
mIntent.putExtra("msg", "自定義的廣播消息");
//開始發(fā)送
sendBroadcast(mIntent);
}
});
}
}
三、 BroadcastReceiver例子
前面我們提到履怯,系統(tǒng)在很多特定的時候會發(fā)送一些廣播川无,我們選擇特定的廣播進行處理,可以實現(xiàn)我們的需要虑乖。
下面展示下怎么獲取手機短信內(nèi)容。
1.新建廣播接收器
public class MessageReceiver extends BroadcastReceiver {
private final String action = "android.provider.Telephony.SMS_RECEIVED";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(action)) {
abortBroadcast();
//用來存放結(jié)果的字符串
StringBuilder sb = new StringBuilder();
//取出信息內(nèi)容的載體
Bundle bundle = intent.getExtras();
//如果內(nèi)容不為空
if (bundle != null) {
//得到信息內(nèi)容 是一段一段的
Object[] pdus = (Object[]) bundle.get("pdus");
//短信對象數(shù)組
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
//循環(huán)遍歷短信數(shù)組 取出內(nèi)容
for (int i = 0; i < messages.length; i++) {
if (i == 0) {
sb.append("發(fā)件人:" + messages[i].getDisplayOriginatingAddress()
+ "\n信息內(nèi)容為:\n");
}
sb.append(messages[i].getDisplayMessageBody() + "\n");
}
Log.e("---sss---", sb.toString());
}
}
}
}
2.清單文件里注冊
<receiver android:name=".receiver.MessageReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
3.添加接收短信的權(quán)限
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
最后可以看到輸出結(jié)果如下:
四晾虑、BroadcastReceiver總結(jié)
下面是對BroadcastReceiver的小結(jié)疹味。
1.廣播的兩種注冊方式
廣播Broadcast的注冊方式有兩種,一種是在清單文件里靜態(tài)注冊帜篇,還有一種是在代碼里動態(tài)注冊糙捺,那么兩種的區(qū)別是什么呢。 通過在配置文件里面注冊廣播屬于常駐型廣播笙隙,即便應用程序結(jié)束洪灯,一旦有了對應的廣播過來,其還是會被激活竟痰;而在代碼里注冊的廣播則是非常駐型廣播签钩,比如在oncreate方法里面注冊一個廣播,那么在ondestroy里就可以BroadcastReceiver.abortBroadcast()坏快。對于第一種方法铅檩,我們需要養(yǎng)成一個良好的習慣:在Activity進入停止或者銷毀狀態(tài)的時候使用unregisterReceiver方法將注冊的BroadcastReceiver注銷掉。如果在清單文件里靜態(tài)注冊莽鸿,那么該對象的實例在onReceive被調(diào)用之后就會在任意時間內(nèi)被銷毀昧旨。也就是說,我們并需要擔心靜態(tài)注冊的BroadcastReceiver的銷毀問題祥得。
2.廣播的兩種類型
廣播Broadcast有兩種類型兔沃,我們通過方法sendBroadcast()發(fā)送的是無序廣播,它是完全異步的级及,可以同時被所有接收者接收到乒疏,消息傳遞效率高,但是接收者不能把處理結(jié)果傳遞給下一個接收者创千,且不能終止廣播的繼續(xù)傳播缰雇。通過sendOrderedBroadcast()發(fā)送的是有序廣播,系統(tǒng)會根據(jù)接收器聲明的優(yōu)先級別按順序逐個接收追驴,先接收廣播的可以使用abortBroadcast()方法終止Broadcast的繼續(xù)傳播械哟,此外,先接收到廣播的還可以通過方法setResultExtras來存數(shù)據(jù)到廣播中殿雪,下一個接收到的可以獲取存入的數(shù)據(jù)暇咆。
3.其它注意點
在新建自己的廣播接收器時,我們要實現(xiàn)onReceive()方法,在里面完成自己的邏輯爸业,這里不能做耗時的操作其骄,建議是10s以內(nèi)。