Android中的廣播主要可以分為兩種類型:標(biāo)準(zhǔn)廣播和有序廣播蒿秦。
一種完全異步執(zhí)行的廣播,在廣播發(fā)出之后蛋济,所有的廣播接收器幾乎都會(huì)在同一時(shí)間接收到這條廣播棍鳖,因此他們之間沒有任何的先后順序。
特點(diǎn):效率高;缺點(diǎn):無法攔截渡处。
一種同步執(zhí)行的廣播镜悉,在廣播發(fā)出之后,同一時(shí)刻只會(huì)有一個(gè)廣播接收器能夠接收到這條廣播医瘫,當(dāng)該廣播接收器執(zhí)行完OnReceive()方法邏輯后侣肄,廣播才會(huì)繼續(xù)傳遞。?
特點(diǎn):優(yōu)先級(jí)高者會(huì)先接收到廣播醇份,并且可以攔截該條廣播是否繼續(xù)傳遞稼锅。
有些廣播可以通過動(dòng)態(tài)(java代碼)靜態(tài)(xml文件)方式任一種來注冊(cè);
有些廣播則必須通過某一種方式來注冊(cè)僚纷,比如開機(jī)廣播必須通過xml方式來注冊(cè)矩距,監(jiān)聽手機(jī)屏幕解鎖開鎖則必須通過java代碼來注冊(cè)。
接收系統(tǒng)廣播
1怖竭,監(jiān)聽手機(jī)是否插入耳機(jī)廣播(動(dòng)態(tài)注冊(cè))
注冊(cè)代碼
intentFilter = new IntentFilter();intentFilter.addAction("android.intent.action.HEADSET_PLUG");registerReceiver(myBrodcast, intentFilter);Toast.makeText(this,"監(jiān)聽耳機(jī)廣播已注冊(cè)", Toast.LENGTH_SHORT).show();
廣播接收器代碼
classMyBrodcastextendsBroadcastReceiver{@OverridepublicvoidonReceive(Context context, Intent intent) {if(null!= intent) {? ? ? ? ? ? ? ? String action = intent.getAction();switch(action) {case"android.intent.action.HEADSET_PLUG":if(intent.hasExtra("state")) {if(intent.getIntExtra("state",0) ==0) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG,"headset not connected");? ? ? ? ? ? ? ? ? ? ? ? ? ? }elseif(intent.getIntExtra("state",0) ==1) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG,"headset connected");? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? }break;? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? }
運(yùn)行插入耳機(jī)锥债、拔出耳機(jī)Log打印:
2痊臭,監(jiān)聽手機(jī)鎖屏解鎖開鎖廣播(動(dòng)態(tài)+靜態(tài))
注冊(cè)代碼
intentFilter = new IntentFilter();intentFilter.addAction(Intent.ACTION_SCREEN_OFF); // 必須代碼來注冊(cè)intentFilter.addAction(Intent.ACTION_SCREEN_ON); // 必須代碼注冊(cè)//? ? ? ? ? ? ? ? intentFilter.addAction(Intent.ACTION_USER_PRESENT); // 可以靜態(tài)注冊(cè)registerReceiver(bootCompleteReceiver, intentFilter);Toast.makeText(this,"鎖屏解鎖廣播已注冊(cè)", Toast.LENGTH_SHORT).show();
xml
廣播接收器
@OverridepublicvoidonReceive(Context context, Intent intent) {// TODO: This method is called when the BroadcastReceiver is receiving// an Intent broadcast.if(null!=intent) {if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {Log.e(TAG,"手機(jī)開屏");? ? ? ? ? ? }elseif(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {Log.e(TAG,"手機(jī)鎖屏");? ? ? ? ? ? }elseif(intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {Log.e(TAG,"手機(jī)解鎖");? ? ? ? ? ? }? ? ? ? }? ? }
運(yùn)行效果圖
3哮肚,監(jiān)聽手機(jī)開機(jī)廣播(靜態(tài)注冊(cè))
注冊(cè)代碼
<!-- 注冊(cè)開機(jī)廣播-->
接收器代碼
case"android.intent.action.BOOT_COMPLETED":Log.e(TAG,"手機(jī)已開機(jī)");? ? ? ? ? ? ? ? ? ? break;
-?發(fā)送自定義廣播
上面講的都是系統(tǒng)廣播,系統(tǒng)廣播需要注冊(cè)趣兄;而自定義廣播則需要人為發(fā)送。?
一般情況使用自定義廣播來實(shí)現(xiàn)某個(gè)功能悼嫉,下面就來看個(gè)例子:接收到自定義廣播后艇潭,啟動(dòng)一個(gè)界面。?
注冊(cè)代碼
<!-- 注冊(cè)開機(jī)廣播--><!--自定義廣播中的action-->
直接使用前面的廣播接收器了戏蔑,在這里增加一個(gè)自定義的 action蹋凝。?
點(diǎn)擊注冊(cè)代碼
Intent intent =newIntent("com.example.mu16jj.broadcastreceiver");? ? ? ? ? ? ? ? sendBroadcast(intent);
接收器代碼
case"com.example.mu16jj.broadcastreceiver":? ? ? ? ? ? ? ? ? ? Log.e(TAG,"我是自定義的");// 在廣播接收器中打開Activity? ? ? ? ? ? ? ? ? ? Intent inten = new Intent(context, MainActivity.class);inten.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(inten);break;
運(yùn)行后Log
-?發(fā)送有序廣播
發(fā)送方式由原來的 sendBroadcast(intent) 改變?yōu)?sendOrderedBroadcast(intent, null),不同的應(yīng)用注冊(cè)同一個(gè)廣播总棵,那么這兩個(gè)(或者更多)都是可以接收到這條廣播的鳍寂。
既然是有序廣播,那么這個(gè)順序的確定就由有一個(gè)屬性來確定情龄,例如:
priority 數(shù)越大優(yōu)先級(jí)別越高迄汛,最大值是2147483647;優(yōu)先級(jí)別也可以調(diào)用 IntentFilter 對(duì)象的 setPriority() 方法進(jìn)行設(shè)置骤视。
當(dāng)然也可以攔截鞍爱,只需要在廣播接收器的 onReceive() 方法中調(diào)用下面一句代碼就可以實(shí)現(xiàn):
abortBroadcast();
使用本地廣播
上面的有序廣播提到了不同的應(yīng)用可以相互接受廣播,那么就存在一個(gè)安全問題专酗,為此睹逃,Android 系統(tǒng)為我們提供了本地廣播管理器類 LocalBroadcastManager,使用它來負(fù)責(zé)應(yīng)用中的廣播發(fā)送祷肯,就相對(duì)安全多了沉填,實(shí)例化方式:
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
當(dāng)然了疗隶,既然是管理器,那么發(fā)送和取消就自然由它負(fù)責(zé)翼闹。
以上的測試手機(jī)版本為5.1.1斑鼻,如果在較高版本運(yùn)行出現(xiàn)關(guān)于動(dòng)態(tài)權(quán)限問題,需要自己手動(dòng)處理橄碾。