標籤:
廣播接收器(BroadcastReceiver)
Android中的廣播主要可以分為兩種類型,標準廣播和有序廣播。
標準廣播(Normal broadcasts):
是一種完全非同步執行的廣播,在廣播發出之後,所有的 廣播接收器幾乎都會在同一時刻接收到這條廣播訊息,
因此它們之間沒有任何先後順序可 言。這種廣播的效率會比較高,但同時也意味著它是無法被截斷的。
有序廣播(Orderedbroadcasts):
則是一種同步執行的廣播,在廣播發出之後,同一時刻 只會有一個廣播接收器能夠收到這條廣播訊息,當這個
廣播接收器中的邏輯執行完畢後,廣 播才會繼續傳遞。所以此時的廣播接收器是有先後順序的,優先順序高的廣
播接收器就可以先 收到廣播訊息,並且前面的廣播接收器還可以截斷正在傳遞的廣播,這樣後面的廣播接收器
就無法收到廣播訊息了。
想要接收到廣播,就需要使用廣播接收器了。
註冊廣播的方式一般有兩種,在代碼中註冊和在 AndroidManifest.xml中註冊,其中前者也被稱為動態註冊,
後者也被稱為靜態註冊。
這是就收廣播的方法:
下面是 動態註冊監聽網路變化
那麼該如何建立一個廣播接收器呢?其實只需要建立一個類,讓它繼承自BroadcastReceiver, 並重寫父類的
onReceive()方法就行了。這樣當有廣播到來時,onReceive()方法就會得到執行, 具體的邏輯就可以在這個方
法中處理。 那我們就先通過動態註冊的方式編寫一個能夠監聽網路變化的程式,藉此學習一下廣播 接收器的基本
用法吧。建立一個 BroadcastTest項目,然後修改 MainActivity中的代碼:
public class MainActivity extends Activity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intentFilter = new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); networkChangeReceiver = new NetworkChangeReceiver(); registerReceiver(networkChangeReceiver, intentFilter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(networkChangeReceiver); } class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show(); } }}
可以看到,我們在 MainActivity 中定義了一個內部類 NetworkChangeReceiver,這個類 是繼承自
BroadcastReceiver的,並重寫了父類的 onReceive()方法。這樣每當網路狀態發生變 化時,onReceive()
方法就會得到執行,這裡只是簡單地使用 Toast提示了一段文本資訊。 然後觀察 onCreate()方法,首先我們
建立了一個 IntentFilter的執行個體,並給它添加了一個 值為 android.net.conn.CONNECTIVITY_CHANGE
的 action,為什麼要添加這個值呢?因為 當網路狀態發生變化時,系統發出的正是一條值為
android.net.conn.CONNECTIVITY_ CHANGE 的廣播,也就是說我們的廣播接收器想要監聽什麼廣播,
就在這裡添加相應的 action就行了。接下來建立了一個 NetworkChangeReceiver的執行個體,然後調用
registerReceiver() 方法進行註冊,將 NetworkChangeReceiver 的執行個體和 IntentFilter 的執行個體都傳了進去
,這樣 NetworkChangeReceiver就會收到所有值為android.net.conn.CONNECTIVITY_CHANGE的廣 播,
也就實現了監聽網路變化的功能。 最後要記得,動態註冊的廣播接收器一定都要取消註冊才行,這裡我們是在
onDestroy() 方法中通過調用 unregisterReceiver()方法來實現的。 整體來說,代碼還是非常簡單的,現在
運行一下程式。首先你會在註冊完成的時候收到 一條廣播,然後按下 Home鍵回到主介面(注意不能按 Back鍵
,否則 onDestroy()方法會執 行) ,接著按下 Menu鍵→Systemsettings→Datausage進入到資料使用詳情
介面,然後嘗試著 開關 MobileData來啟動和禁用網路,你就會看到有 Toast提醒你網路發生了變化。 不過只
是提醒網路發生了變化還不夠人性化,最好是能準確地告訴使用者當前是有網路還 是沒有網路,因此我們還需要
對上面的代碼進行進一步的最佳化。修改 MainActivity中的代碼:
public class MainActivity extends Activity { class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager connectionManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfonetworkInfo = connectionManager.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isAvailable()) { Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show(); } } }}
在onReceive()方法中,首先通過get getSystemService()方法得到了 ConnectivityManager的
執行個體,這是一個系統服務類,專門用於管理網路連接的。然後調用它的 getActiveNetworkInfo()
方法可以得到 NetworkInfo的執行個體,接著調用 NetworkInfo的 isAvailable()方法,就可以判斷
出當前是否有網路了,最後我們還是通過 Toast的方式對使用者進行提示。
另外要注意:
Android系統為了保證應用程式的安全性做了 規定,如果程式需要訪問一些系統的關
鍵性資訊,必須在設定檔中聲明許可權才可以,否則 程式將會直接崩潰,比如這裡查詢系統的網路
狀態就是需要聲明許可權的。開啟 AndroidManifest.xml檔案,在裡面加入如下許可權就可以查詢系統
網路狀態了:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.broadcasttest"android:versionCode="1"android:versionName="1.0"><uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />……</manifest>
然後就可以再android的應用中查看這些已經聲明的許可權了。
現在再次運行就看裡看到來自系統的提示了。
還有一個就是
靜態註冊實現開機啟動 這個我還不是太明白所以沒打算寫 等等明白了就決定寫下來。
2, 靜態註冊實現開機啟動:(連結)
android開發之 廣播機制