Android学习笔记(十三)
Android中的廣播機制
Android提供了一套完整的API,允許應用程序自由地發送和接受廣播。
發送廣播的方法借助于Intent,接受廣播的方法需要廣播接收器(BroadcastsReceiver)。
Android中的廣播主要分為兩種類型,標準廣播和有序廣播。
?
標準廣播(Normal broadcasts)是一種完全異步執行的廣播,在廣播發出之后,所有的廣播接收器幾乎都會在
同一時刻接受到這條廣播消息。
有序廣播(Ordered broadcasts)是一種同步執行的廣播,在廣播發出之后,同一時刻只會有一個廣播接收器能夠收到這條廣播的消息,
當這個廣播接收器中的邏輯執行完畢后,廣播才會繼續傳遞。(這樣,前面的廣播接收器就可以截斷正在傳遞的廣播)
?
廣播接收器可以自由地對自己感興趣的廣播進行注冊,這樣當有相應的廣播發出時,廣播接收器就能夠收到該廣播,
并在內部處理相應的邏輯。
注冊廣播的方式一般有兩種,在代碼中注冊(也稱為動態注冊)和在AndroidManifest.xml中注冊(也稱為靜態注冊)。
?
廣播接收器的創建:新建一個類,讓其繼承自BroadcastsReceiver,并重寫父類的onReceive()方法。
這樣當有廣播到來時,onReceive()方法就會執行,具體的邏輯就可以在這個方法中處理。
?
下面通過動態注冊的方法編寫一個能夠監聽網絡變化的程序。新建一個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 //創建一個IntentFilter的實例 12 intentFilter = new IntentFilter(); 13 //廣播接收器想要監聽什么廣播,就在這里添加相應的action 14 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); 15 //創建一個NetworkChangeReceiver的實例 16 networkChangeReceiver = new NetworkChangeReceiver(); 17 //調用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 //動態注冊的廣播接收器一定要取消注冊 48 unregisterReceiver(networkChangeReceiver); 49 } 50 51 //定義一個內部類 52 class NetworkChangeReceiver extends BroadcastReceiver { 53 @Override 54 public void onReceive(Context context, Intent intent) { 55 //通過getSystemService()方法得到ConnectivityManager的實例,這是一個系統服務類, 56 // 專門用于管理網絡連接的 57 ConnectivityManager connectivityManager = 58 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 59 //調用ConnectivityManager的getActiveNetworkInfo()方法可以得到NetworkInfo的實例 60 NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 61 //調用NetworkInfo的isAvailable()方法,就可以判斷當前是否有網絡了 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中定義了一個內部類NetworkChangeReceiver,這個類是繼承自BroadcastsReceiver的,
并重寫了onReceive()方法。這樣每當系統的網絡狀態發生變化時,onReceive()中的方法就會執行。
在onReceive()方法中,首先通過getSystemService()方法得到ConnectivityManager的實例,這時一個系統服務類,專門用于
管理網絡的。
然后調用ConnectivityManager的getActiveNetworkInfo()方法得到NetworkInfo的實例,接著調用NetworkInfo的isAvailable()方法,
就可以判斷是否有網絡了。
onCreate()方法中,首先創建了一個IntentFilter的實例,給它添加一個值為android.net.conn.CONNECTIVITY_CHANGE的action。網絡
發生變化時,系統發出的正是一條值為android.net.conn.CONNECTIVITY_CHANGE的廣播。
接下來創建一個NetworkChangeReceiver的實例,然后調用registerReceiver()方法進行注冊,將NetworkChangeReceiver的實例和
IntentFilter的實例都傳遞進去,這樣NetworkChangeReceiver就會收到所有值為android.net.conn.CONNECTIVITY_CHANGE的廣播。
?
注意:動態注冊的廣播接收器一定要取消注冊才行,這里在onDestroy()方法中通過調用unregisterReceiver()方法來實現。
代碼如下所示:
protected void onDestroy() {super.onDestroy();//動態注冊的廣播接收器一定要取消注冊 unregisterReceiver(networkChangeReceiver);}?
Android系統為了保證應用程序的安全性做了規定,如果程序要訪問一些系統的關鍵性信息,必須要在AndroidManifest.xml文件中聲明權限才可以。
例如下面的代碼中就為查詢系統的網絡狀態聲明的權限,代碼如下所示:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.mfeng.glh.broadcasttest" ><!-- 添加查詢系統網絡狀態的權限聲明 --><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>運行程序,在系統設置中切換網絡就可以收到廣播消息了。
?
動態注冊的廣播可以自由的控制注冊和注銷,但是必須要程序啟動以后才能接收廣播。
如果想讓程序在未啟動的情況下接收廣播,就要用的靜態注冊。
下面就使用靜態注冊的方法,接收一條開機廣播,從而實現開機啟動的功能。
新建一個BootCompleteReceiver類繼承自BroadcastsReceiver,代碼如下所示:
public class BootCompleteReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show();} }這里就不在使用內部類的方式來定義廣播接收器了。在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" ><!-- 添加查詢系統網絡狀態的權限聲明 --><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>標簽內出現了一個新的標簽<receiver>,所有靜態注冊的廣播接收器都是在這里進行注冊的。
其中android:name指定具體注冊哪一個廣播接收器,然后在<intent-filter>標簽中加入想要接收的廣播就行了。
注意:監聽系統開機廣播也是需要聲明權限的。
重新運行程序,就可以接收開機廣播了。打開系統的應用程序管理界面,查看一下當前程序所擁有的權限,
如下圖所示:
從圖中可以看到,程序查看網絡連接狀態和開機啟動的權限。
轉載于:https://www.cnblogs.com/mffeng/p/4743706.html
總結
以上是生活随笔為你收集整理的Android学习笔记(十三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java armeabi_armeabi
- 下一篇: mysql触发器报错_mysql触发器实