android菜鳥學習筆記26----Android廣播消息及BroadcastReceiver

1.廣播類型android

Android中的廣播有兩種類型:標準廣播和有序廣播。其中,標準廣播是徹底異步發送的廣播,發出以後,幾乎全部的廣播接收者都會在同一時刻收到這條廣播消息,於是,這種類型的廣播消息是不可攔截,不可修改的;而有序廣播是一種同步發送的廣播,廣播發出後,只有優先級最高的廣播接收者可以收到這條廣播消息,它處理完本身的邏輯以後,廣播纔會向後繼續傳遞給低優先級的廣播接收者,所以,高優先級的廣播接收者能夠對廣播消息進行攔截,修改操做。網絡

2.接收系統廣播app

要接收系統廣播,就要有本身的廣播接收者。定義一個本身的廣播接收者的方式就是自定義一個類繼承自BroadcastReceiver,而後重寫其onReceive()方法便可,在onReceive()方法中能夠實現廣播消息的獲取,修改等操做,固然能修改的只有有序廣播。異步

BroadcastReceiver中的經常使用方法:ide

 

getResultCode()、getResultData()、getResultExtras()分別用來獲取廣播的代碼,數據及附加數據信息,通常是前一個廣播接收者所設定的。測試

 

setXX()與上面的getXX()對應,用來進行相應的設置,後一個廣播接收者獲取的將是當前設置的數據。this

 

abortBradcast()截斷當前廣播。spa

2.1接收向外撥號的廣播.net

1)定義廣播接收器並重寫onReceive()方法:線程

 1 public class OutCallingReceiver extends BroadcastReceiver {
 2 
 3       @Override
 4 
 5       public void onReceive(Context context, Intent intent) {
 6 
 7            // TODO Auto-generated method stub
 8 
 9            String number = this.getResultData();
10 
11            if(number.equals("10086")){
12 
13                  this.setResultData("110");
14 
15            }else if(number.equals("10000")){
16 
17                  this.setResultData("120");
18 
19            }else{
20 
21                  this.setResultData("2222");
22 
23            }
24 
25            Toast.makeText(context, "轉發成功", Toast.LENGTH_SHORT).show();
26 
27       }
28 
29 }

2)在Manifest.xml清單文件的<application>節點下中註冊廣播接收者組件,聲明其能接收的廣播爲向外撥號:

1 <receiver android:name="cn.csc.broadcast.OutCallingReceiver">
2 
3             <intent-filter >
4 
5                 <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
6 
7             </intent-filter>
8 
9 </receiver>

3)因爲重寫的onReceive()方法中修改了廣播,對向外撥出的號碼進行了修改,因此須要配置權限:

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

 

4)運行結果:

部署到模擬器後,而後撥號:

 

被處理以後:

 

2.2接收網絡狀態變化的廣播:參考《第一行代碼》

1)定義廣播接收器並重寫onReceive()方法:

 1 public class NetworkReceiver extends BroadcastReceiver {
 2 
 3  
 4 
 5       @Override
 6 
 7       public void onReceive(Context context, Intent intent) {
 8 
 9            // TODO Auto-generated method stub
10 
11            ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
12 
13            NetworkInfo info = connManager.getActiveNetworkInfo();
14 
15            if(info != null && info.isAvailable()){
16 
17                  Toast.makeText(context, "網絡可用", Toast.LENGTH_SHORT).show();
18 
19            }else{
20 
21                  Toast.makeText(context, "網絡不可用", Toast.LENGTH_SHORT).show();
22 
23            }
24 
25       }
26 
27 }

2)在Manifest.xml清單文件的<application>節點下中註冊廣播接收者組件:

1 <receiver android:name="cn.csc.broadcast.NetworkReceiver">
2 
3             <intent-filter >
4 
5                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
6 
7             </intent-filter>
8 
9 </receiver>

3)須要配置權限讀取網絡狀態的權限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

 

4)運行結果:

部署到模擬器後,在配置中修改網絡狀態:

設置爲飛行模式,網絡不可用:

 

關閉飛行模式,網絡變爲可用:

 

關閉手機移動網絡:

 

開啓手機移動網絡:

 

3.發送廣播:

須要用到Context的如下方法:

 

sendBroadcast(Intent intent):傳入一個意圖,而後根據意圖發出一個標準廣播。

sendBroadcast(Intent intent, String receiverPermission):傳入一個意圖及一個字符串表示的權限,指定聲明改權限的廣播接收者才能收到這個廣播,第二個參數爲null的話,表示不須要聲明權限。

sendOrderedBroadcast(Intent intent, String receiverPermission):參數含義同上一個方法,不一樣的是該方法發送一個有序廣播。

sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras):一樣是發送一個有序廣播,多出來的參數含義以下:

resultReceiver:指定最終的接收者,不須要則設爲null

scheduler:指定自定義的Handler執行resultReceiver的回調,null則在主線程執行

initalCode:爲resultCode設置初始值

initalData:爲resultData設置初始值

initalExtras:爲resultExtras設置初始值

3.1發送標準廣播

1)修改應用的Activity,添加一個按鈕,按鈕的單擊響應監聽中發送自定義廣播:

 1 Button btn = (Button) findViewById(R.id.btn_send_normal);
 2 
 3         btn.setOnClickListener(new OnClickListener() {
 4 
 5                 
 6 
 7                  @Override
 8 
 9                  public void onClick(View v) {
10 
11                       // TODO Auto-generated method stub
12 
13                       Intent intent = new Intent("cn.csc.broadcast.PARTY");
14 
15                       intent.putExtra("content", "明天下午16點校南門集合,一塊兒去龍湖看電影,聚餐");
16 
17                       sendBroadcast(intent);
18 
19                  }
20 
21            });

 

2)自定義廣播接收器,接收本身發送的聚餐廣播:

 1 public class PartyReceiver extends BroadcastReceiver {
 2 
 3       @Override
 4 
 5       public void onReceive(Context context, Intent intent) {
 6 
 7            // TODO Auto-generated method stub
 8 
 9            Toast.makeText(context, intent.getStringExtra("content"), Toast.LENGTH_LONG).show();
10 
11       }
12 
13 }

3)在清單文件中,配置PartyReceiver:

1 <receiver android:name="cn.csc.broadcast.PartyReceiver">
2 
3             <intent-filter >
4 
5                 <action android:name="cn.csc.broadcast.PARTY"/>
6 
7             </intent-filter>
8 
9 </receiver>

4)運行結果:

 

3.2發送有序廣播:

1)修改按鈕單擊事件監聽:

sendOrderedBroadcast(intent, null, null, null, 0, "明天下午16點校南門集合,一塊兒去龍湖看電影,聚餐", null);

 

2)新建幾個接收聚餐廣播的接收者:

能夠直接複製原來的那個,簡單修改標識便可,採用Logcat輸出消息:

 1 public class PartyReceiver1 extends BroadcastReceiver {
 2 
 3       @Override
 4 
 5       public void onReceive(Context context, Intent intent) {
 6 
 7            // TODO Auto-generated method stub
 8 
 9            Log.i("PARTY","F1:"+ getResultData());
10 
11       }
12 
13 }

 

3)在清單文件中註冊:

 1 <receiver android:name="cn.csc.broadcast.PartyReceiver1">
 2 
 3             <intent-filter >
 4 
 5                 <action android:name="cn.csc.broadcast.PARTY"/>
 6 
 7             </intent-filter>
 8 
 9         </receiver>
10 
11         <receiver android:name="cn.csc.broadcast.PartyReceiver2">
12 
13             <intent-filter >
14 
15                 <action android:name="cn.csc.broadcast.PARTY"/>
16 
17             </intent-filter>
18 
19         </receiver>
20 
21         <receiver android:name="cn.csc.broadcast.PartyReceiver3">
22 
23             <intent-filter >
24 
25                 <action android:name="cn.csc.broadcast.PARTY"/>
26 
27             </intent-filter>
28 
29         </receiver>

4)運行結果:

 

多點幾回按鈕,順序仍然同樣。這裏沒有設置優先級,就按清單文件中的順序一個個向下傳遞。

5)修改清單文件,添加優先級:

 1 <receiver android:name="cn.csc.broadcast.PartyReceiver1">
 2 
 3             <intent-filter android:priority="0">
 4 
 5                 <action android:name="cn.csc.broadcast.PARTY"/>
 6 
 7             </intent-filter>
 8 
 9         </receiver>
10 
11         <receiver android:name="cn.csc.broadcast.PartyReceiver2">
12 
13             <intent-filter android:priority="500">
14 
15                 <action android:name="cn.csc.broadcast.PARTY"/>
16 
17             </intent-filter>
18 
19         </receiver>
20 
21         <receiver android:name="cn.csc.broadcast.PartyReceiver3">
22 
23             <intent-filter android:priority="1000">
24 
25                 <action android:name="cn.csc.broadcast.PARTY"/>
26 
27             </intent-filter>
28 
29         </receiver>

6)從新運行:

 

優先級數字越大,優先級就越高。

若優先級全設置爲500:

可見,優先級相同則按註冊順序依次傳遞。

7)設置不一樣的優先級,而後在高優先級Receiver中修改消息內容:

Receiver1:

1 Log.i("PARTY","F1:"+getResultData());
2 
3 setResultData("明天早上5點校西門集合,一塊兒去春熙路看美女");

 

Receiver2:

1 Log.i("PARTY","F2:"+getResultData());
2 
3 setResultData("明天自由活動");

Receiver3:

Log.i("PARTY","F3:"+getResultData());

 

8)運行結果:

 

9)高優先級截斷廣播消息:

Receiver1:

1 Log.i("PARTY","F1:"+getResultData());
2 
3 setResultData("明天早上5點校西門集合,一塊兒去春熙路看美女");
4 
5 abortBroadcast();

運行結果:

 

10)設置sendOrderedBroadcast()方法的resultReceiver參數:

sendOrderedBroadcast(intent, null, new PartyReceiver3(), null, 0, "明天下午16點校南門集合,一塊兒去龍湖看電影,聚餐", null);

 

Receiver1中任然截獲廣播消息:

1 Log.i("PARTY","F1:"+getResultData());
2 
3 setResultData("明天早上5點校西門集合,一塊兒去春熙路看美女");
4 
5 abortBroadcast();

運行結果:

 

可見,resultReceiver指定的接收者,即便高優先級接收者截獲廣播消息,它也必定能收到廣播消息。

以上,就是學到的Android中關於廣播接收者的內容。

 

補充:本地廣播的簡單使用,參考《第一行代碼》

1)修改Activity代碼:

 1 public class MainActivity extends ActionBarActivity {
 2 
 3       private LocalBroadcastManager manager;
 4 
 5       private LocalReceiver localReceiver;
 6 
 7     @Override
 8 
 9     protected void onCreate(Bundle savedInstanceState) {
10 
11         super.onCreate(savedInstanceState);
12 
13         setContentView(R.layout.activity_main);
14 
15         Button btn = (Button) findViewById(R.id.btn_send_normal);
16 
17         manager = LocalBroadcastManager.getInstance(this);
18 
19         btn.setOnClickListener(new OnClickListener() {
20 
21                  @Override
22 
23                  public void onClick(View v) {
24 
25                       // TODO Auto-generated method stub
26 
27                       Intent intent = new Intent("cn.csc.broadcast.PARTY");
28 
29                       intent.putExtra("content", "明天下午16點校南門集合,一塊兒去龍湖看電影,聚餐");
30 
31                       manager.sendBroadcast(intent);
32 
33                  }
34 
35           
36 
37         });
38 
39         IntentFilter filter = new IntentFilter();
40 
41         filter.addAction("cn.csc.broadcast.PARTY");
42 
43         localReceiver = new LocalReceiver();
44 
45         manager.registerReceiver(localReceiver, filter);
46 
47     }
48 
49  
50 
51       @Override
52 
53       protected void onDestroy() {
54 
55            // TODO Auto-generated method stub
56 
57            manager.unregisterReceiver(localReceiver);
58 
59       }
60 
61 }

主要就是以前有Context調用sendBroadcast()改成由LocalBroadcastManager調用,及註冊接收者。

2)新建一個接收本地廣播的接收者:

 1 public class LocalReceiver extends BroadcastReceiver {
 2 
 3  
 4 
 5       @Override
 6 
 7       public void onReceive(Context context, Intent intent) {
 8 
 9            // TODO Auto-generated method stub
10 
11            Toast.makeText(context, intent.getStringExtra("content"), Toast.LENGTH_LONG).show();
12 
13       }
14 
15 }

 

這樣,這個廣播就只能在本應用中可見,該應用以外不可見了。

注意一點,本地廣播中這種廣播接收者註冊方式稱之爲動態註冊,而前面的全局廣播接收者註冊是在清單文件中註冊的,稱之爲靜態註冊,前面的廣播接收者的註冊也均可以使用動態註冊,在此就不一一測試了。靜態註冊的好處是即便不啓動應用,也可以接收廣播消息進行須要的簡單處理。而本地廣播是當前應用發出的只在本應用內部可見的廣播消息,因此只能採用動態註冊,並且徹底不必採用靜態註冊,能發出廣播消息就說明該應用已然處於啓動的狀態了。

相關文章
相關標籤/搜索