Android学习笔记(十三)
Android中的廣播機制
Android提供了一套完整的API,允許應(yīng)用程序自由地發(fā)送和接受廣播。
發(fā)送廣播的方法借助于Intent,接受廣播的方法需要廣播接收器(BroadcastsReceiver)。
Android中的廣播主要分為兩種類型,標準廣播和有序廣播。
?
標準廣播(Normal broadcasts)是一種完全異步執(zhí)行的廣播,在廣播發(fā)出之后,所有的廣播接收器幾乎都會在
同一時刻接受到這條廣播消息。
有序廣播(Ordered broadcasts)是一種同步執(zhí)行的廣播,在廣播發(fā)出之后,同一時刻只會有一個廣播接收器能夠收到這條廣播的消息,
當這個廣播接收器中的邏輯執(zhí)行完畢后,廣播才會繼續(xù)傳遞。(這樣,前面的廣播接收器就可以截斷正在傳遞的廣播)
?
廣播接收器可以自由地對自己感興趣的廣播進行注冊,這樣當有相應(yīng)的廣播發(fā)出時,廣播接收器就能夠收到該廣播,
并在內(nèi)部處理相應(yīng)的邏輯。
注冊廣播的方式一般有兩種,在代碼中注冊(也稱為動態(tài)注冊)和在AndroidManifest.xml中注冊(也稱為靜態(tài)注冊)。
?
廣播接收器的創(chuàng)建:新建一個類,讓其繼承自BroadcastsReceiver,并重寫父類的onReceive()方法。
這樣當有廣播到來時,onReceive()方法就會執(zhí)行,具體的邏輯就可以在這個方法中處理。
?
下面通過動態(tài)注冊的方法編寫一個能夠監(jiān)聽網(wǎng)絡(luò)變化的程序。新建一個BroadcastTest項目,
然后修改MainActivity中的代碼,如下所示:
1 public class MainActivity extends AppCompatActivity { 2 3 private IntentFilter intentFilter; 4 5 private NetworkChangeReceiver networkChangeReceiver; 6 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_main); 11 //創(chuàng)建一個IntentFilter的實例 12 intentFilter = new IntentFilter(); 13 //廣播接收器想要監(jiān)聽什么廣播,就在這里添加相應(yīng)的action 14 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); 15 //創(chuàng)建一個NetworkChangeReceiver的實例 16 networkChangeReceiver = new NetworkChangeReceiver(); 17 //調(diào)用registerReceiver()方法進行注冊,將NetworkChangeReceiver的實例和IntentFilter的實例都傳遞進去 18 registerReceiver(networkChangeReceiver,intentFilter); 19 20 } 21 22 @Override 23 public boolean onCreateOptionsMenu(Menu menu) { 24 // Inflate the menu; this adds items to the action bar if it is present. 25 getMenuInflater().inflate(R.menu.menu_main, menu); 26 return true; 27 } 28 29 @Override 30 public boolean onOptionsItemSelected(MenuItem item) { 31 // Handle action bar item clicks here. The action bar will 32 // automatically handle clicks on the Home/Up button, so long 33 // as you specify a parent activity in AndroidManifest.xml. 34 int id = item.getItemId(); 35 36 //noinspection SimplifiableIfStatement 37 if (id == R.id.action_settings) { 38 return true; 39 } 40 41 return super.onOptionsItemSelected(item); 42 } 43 44 @Override 45 protected void onDestroy() { 46 super.onDestroy(); 47 //動態(tài)注冊的廣播接收器一定要取消注冊 48 unregisterReceiver(networkChangeReceiver); 49 } 50 51 //定義一個內(nèi)部類 52 class NetworkChangeReceiver extends BroadcastReceiver { 53 @Override 54 public void onReceive(Context context, Intent intent) { 55 //通過getSystemService()方法得到ConnectivityManager的實例,這是一個系統(tǒng)服務(wù)類, 56 // 專門用于管理網(wǎng)絡(luò)連接的 57 ConnectivityManager connectivityManager = 58 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 59 //調(diào)用ConnectivityManager的getActiveNetworkInfo()方法可以得到NetworkInfo的實例 60 NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 61 //調(diào)用NetworkInfo的isAvailable()方法,就可以判斷當前是否有網(wǎng)絡(luò)了 62 if (networkInfo != null && networkInfo.isAvailable()) { 63 Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show(); 64 }else { 65 Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show(); 66 } 67 68 } 69 } 70 }上面的代碼中可以看到,在MainActivity中定義了一個內(nèi)部類NetworkChangeReceiver,這個類是繼承自BroadcastsReceiver的,
并重寫了onReceive()方法。這樣每當系統(tǒng)的網(wǎng)絡(luò)狀態(tài)發(fā)生變化時,onReceive()中的方法就會執(zhí)行。
在onReceive()方法中,首先通過getSystemService()方法得到ConnectivityManager的實例,這時一個系統(tǒng)服務(wù)類,專門用于
管理網(wǎng)絡(luò)的。
然后調(diào)用ConnectivityManager的getActiveNetworkInfo()方法得到NetworkInfo的實例,接著調(diào)用NetworkInfo的isAvailable()方法,
就可以判斷是否有網(wǎng)絡(luò)了。
onCreate()方法中,首先創(chuàng)建了一個IntentFilter的實例,給它添加一個值為android.net.conn.CONNECTIVITY_CHANGE的action。網(wǎng)絡(luò)
發(fā)生變化時,系統(tǒng)發(fā)出的正是一條值為android.net.conn.CONNECTIVITY_CHANGE的廣播。
接下來創(chuàng)建一個NetworkChangeReceiver的實例,然后調(diào)用registerReceiver()方法進行注冊,將NetworkChangeReceiver的實例和
IntentFilter的實例都傳遞進去,這樣NetworkChangeReceiver就會收到所有值為android.net.conn.CONNECTIVITY_CHANGE的廣播。
?
注意:動態(tài)注冊的廣播接收器一定要取消注冊才行,這里在onDestroy()方法中通過調(diào)用unregisterReceiver()方法來實現(xiàn)。
代碼如下所示:
protected void onDestroy() {super.onDestroy();//動態(tài)注冊的廣播接收器一定要取消注冊 unregisterReceiver(networkChangeReceiver);}?
Android系統(tǒng)為了保證應(yīng)用程序的安全性做了規(guī)定,如果程序要訪問一些系統(tǒng)的關(guān)鍵性信息,必須要在AndroidManifest.xml文件中聲明權(quán)限才可以。
例如下面的代碼中就為查詢系統(tǒng)的網(wǎng)絡(luò)狀態(tài)聲明的權(quán)限,代碼如下所示:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.mfeng.glh.broadcasttest" ><!-- 添加查詢系統(tǒng)網(wǎng)絡(luò)狀態(tài)的權(quán)限聲明 --><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>運行程序,在系統(tǒng)設(shè)置中切換網(wǎng)絡(luò)就可以收到廣播消息了。
?
動態(tài)注冊的廣播可以自由的控制注冊和注銷,但是必須要程序啟動以后才能接收廣播。
如果想讓程序在未啟動的情況下接收廣播,就要用的靜態(tài)注冊。
下面就使用靜態(tài)注冊的方法,接收一條開機廣播,從而實現(xiàn)開機啟動的功能。
新建一個BootCompleteReceiver類繼承自BroadcastsReceiver,代碼如下所示:
public class BootCompleteReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show();} }這里就不在使用內(nèi)部類的方式來定義廣播接收器了。在onReceive()方法中,簡單的彈出一段提示信息。
然后修改AndroidManifest.xml文件,代碼如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.mfeng.glh.broadcasttest" ><!-- 添加查詢系統(tǒng)網(wǎng)絡(luò)狀態(tài)的權(quán)限聲明 --><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><receiver android:name=".BootCompleteReceiver" ><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter></receiver></application></manifest>上面的代碼中,在<application>標簽內(nèi)出現(xiàn)了一個新的標簽<receiver>,所有靜態(tài)注冊的廣播接收器都是在這里進行注冊的。
其中android:name指定具體注冊哪一個廣播接收器,然后在<intent-filter>標簽中加入想要接收的廣播就行了。
注意:監(jiān)聽系統(tǒng)開機廣播也是需要聲明權(quán)限的。
重新運行程序,就可以接收開機廣播了。打開系統(tǒng)的應(yīng)用程序管理界面,查看一下當前程序所擁有的權(quán)限,
如下圖所示:
從圖中可以看到,程序查看網(wǎng)絡(luò)連接狀態(tài)和開機啟動的權(quán)限。
轉(zhuǎn)載于:https://www.cnblogs.com/mffeng/p/4743706.html
總結(jié)
以上是生活随笔為你收集整理的Android学习笔记(十三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java armeabi_armeabi
- 下一篇: Android中Activity启动模式