1)請(qǐng)描述一下廣播BroadcastReceiver的理解
2)廣播的分類
3)廣播使用的方式和場(chǎng)景
4)在manifest 和代碼中如何注冊(cè)和使用BroadcastReceiver?
5)本地廣播和全局廣播有什么差別?(應(yīng)用內(nèi)和應(yīng)用外)
6)如何通過廣播攔截和abort一條短信?
7)廣播是否可以請(qǐng)求網(wǎng)絡(luò)?
一.理解:
用于監(jiān)聽(接收)應(yīng)用發(fā)出的廣播消息,并做出響應(yīng)
二. 分類:
普通、系統(tǒng)、有序、本地、粘性廣播。
三. 方式:
- 自定義廣播接收者BroadcastReceiver子類,并復(fù)寫onRecvice()方法;
- 通過Binder機(jī)制向AMS(Activity Manager Service)進(jìn)行注冊(cè); 分為靜態(tài)和動(dòng)態(tài)。
- 廣播發(fā)送者通過Binder機(jī)制向AMS發(fā)送廣播;
- AMS查找符合相應(yīng)條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發(fā)送到
- BroadcastReceiver(一般情況下是Activity)相應(yīng)的消息循環(huán)隊(duì)列中;
- 消息循環(huán)執(zhí)行拿到此廣播,回調(diào)BroadcastReceiver中的onReceive()方法。
場(chǎng)景:
四. 動(dòng)態(tài)與靜態(tài)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//實(shí)例化BroadcastReceiver子類 & IntentFilter
mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//設(shè)置接收廣播的類型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//調(diào)用Context的registerReceiver()方法進(jìn)行動(dòng)態(tài)注冊(cè)
registerReceiver(mBroadcastReceiver, intentFilter);
}
<receiver
//此廣播接收者類是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用于接收網(wǎng)絡(luò)狀態(tài)改變時(shí)發(fā)出的廣播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
六. 如何通過廣播攔截和abort一條短信?
public class SmsReceiver extends BroadcastReceiver {
// 當(dāng)接收到短信時(shí)被觸發(fā)
@Override
public void onReceive(Context context, Intent intent) {
// 如果是接收到短信
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
// 取消廣播(這行代碼將會(huì)讓系統(tǒng)收不到短信)
abortBroadcast();
StringBuilder sb = new StringBuilder();
// 接收由SMS傳過來的數(shù)據(jù)
Bundle bundle = intent.getExtras();
// 判斷是否有數(shù)據(jù)
if (bundle != null) {
// 通過pdus可以獲得接收到的所有短信消息
Object[] pdus = (Object[]) bundle.get("pdus");
// 構(gòu)建短信對(duì)象array,并依據(jù)收到的對(duì)象長(zhǎng)度來創(chuàng)建array的大小
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
// 將送來的短信合并自定義信息于StringBuilder當(dāng)中
for (SmsMessage message : messages) {
sb.append("短信來源:");
// 獲得接收短信的電話號(hào)碼
sb.append(message.getDisplayOriginatingAddress());
sb.append("\n------短信內(nèi)容------\n");
// 獲得短信的內(nèi)容
sb.append(message.getDisplayMessageBody());
}
}
Toast.makeText(context, sb.toString(), 5000).show();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="wuchen.broadcastReceiver"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<receiver android:name=".SmsReceiver" >
<intent-filter android:priority="800" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
<!-- 授予程序接收短信的權(quán)限 -->
<uses-permission android:name="android.permission.RECEIVE_SMS" />
</manifest>
七. 廣播中可以打開網(wǎng)絡(luò)?
需要單開子線程否則容易導(dǎo)致ANR 。 Broadcast 10s