基礎總結篇之五:BroadcastReceiver應用詳解

轉載 http://blog.csdn.net/liuhe688/article/details/6955668

問渠那得清如許?為有源頭活水來。南宋.朱熹《觀書有感》

據說程序員是最愛學習的羣體,IT男都知道,這個行業日新月異,必須不斷地學習新知識,不斷地爲自己注入新鮮的血液,才能使自己跟上技術的步伐。

今天我們來講一下Android中BroadcastReceiver的相關知識。

BroadcastReceiver也就是“廣播接收者”的意思,顧名思義,它就是用來接收來自系統和應用中的廣播。

在Android系統中,廣播體現在方方面面,例如當開機完成後系統會產生一條廣播,接收到這條廣播就能實現開機啓動服務的功能;當網絡狀態改變時系統會產生一條廣播,接收到這條廣播就能及時地做出提示和保存數據等操作;當電池電量改變時,系統會產生一條廣播,接收到這條廣播就能在電量低時告知用戶及時保存進度,等等。

Android中的廣播機制設計的非常出色,很多事情原本需要開發者親自操作的,現在只需等待廣播告知自己就可以了,大大減少了開發的工作量和開發週期。而作爲應用開發者,就需要數練掌握Android系統提供的一個開發利器,那就是BroadcastReceiver。下面我們就對BroadcastReceiver逐一地分析和演練,瞭解和掌握它的各種功能和用法。

首先,我們來演示一下創建一個BroadcastReceiver,並讓這個BroadcastReceiver能夠根據我們的需要來運行。

要創建自己的BroadcastReceiver對象,我們需要繼承android.content.BroadcastReceiver,並實現其onReceive方法。下面我們就創建一個名爲MyReceiver廣播接收者:

  1. package com.scott.receiver;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.util.Log;  
  7.   
  8. public class MyReceiver extends BroadcastReceiver {  
  9.       
  10.     private static final String TAG = “MyReceiver”;  
  11.       
  12.     @Override  
  13.     public void onReceive(Context context, Intent intent) {  
  14.         String msg = intent.getStringExtra(”msg”);  
  15.         Log.i(TAG, msg);  
  16.     }  
  17.   
  18. }  
package com.scott.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyReceiver extends BroadcastReceiver {

    private static final String TAG = "MyReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, msg);
    }

}

在onReceive方法內,我們可以獲取隨廣播而來的Intent中的數據,這非常重要,就像無線電一樣,包含很多有用的信息。

在創建完我們的BroadcastReceiver之後,還不能夠使它進入工作狀態,我們需要爲它註冊一個指定的廣播地址。沒有註冊廣播地址的BroadcastReceiver就像一個缺少選臺按鈕的收音機,雖然功能俱備,但也無法收到電臺的信號。下面我們就來介紹一下如何爲BroadcastReceiver註冊廣播地址。

靜態註冊

靜態註冊是在AndroidManifest.xml文件中配置的,我們就來爲MyReceiver註冊一個廣播地址:

  1. <receiver android:name=“.MyReceiver”>  
  2.             <intent-filter>  
  3.                 <action android:name=“android.intent.action.MY_BROADCAST”/>  
  4.                 <category android:name=“android.intent.category.DEFAULT” />  
  5.             </intent-filter>  
  6.         </receiver>  
<receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="android.intent.action.MY_BROADCAST"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

配置了以上信息之後,只要是android.intent.action.MY_BROADCAST這個地址的廣播,MyReceiver都能夠接收的到。注意,這種方式的註冊是常駐型的,也就是說當應用關閉後,如果有廣播信息傳來,MyReceiver也會被系統調用而自動運行。

動態註冊

動態註冊需要在代碼中動態的指定廣播地址並註冊,通常我們是在Activity或Service註冊一個廣播,下面我們就來看一下注冊的代碼:

  1. MyReceiver receiver = new MyReceiver();  
  2.           
  3. IntentFilter filter = new IntentFilter();  
  4. filter.addAction(”android.intent.action.MY_BROADCAST”);  
  5.           
  6. registerReceiver(receiver, filter);  
MyReceiver receiver = new MyReceiver();

IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.MY_BROADCAST");

registerReceiver(receiver, filter);
注意,registerReceiver是android.content.ContextWrapper類中的方法,Activity和Service都繼承了ContextWrapper,所以可以直接調用。在實際應用中,我們在Activity或Service中註冊了一個BroadcastReceiver,當這個Activity或Service被銷燬時如果沒有解除註冊,系統會報一個異常,提示我們是否忘記解除註冊了。所以,記得在特定的地方執行解除註冊操作:

  1. @Override  
  2. protected void onDestroy() {  
  3.     super.onDestroy();  
  4.     unregisterReceiver(receiver);  
  5. }  
@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(receiver);
}

執行這樣行代碼就可以解決問題了。注意,這種註冊方式與靜態註冊相反,不是常駐型的,也就是說廣播會跟隨程序的生命週期。

我們可以根據以上任意一種方法完成註冊,當註冊完成之後,這個接收者就可以正常工作了。我們可以用以下方式向其發送一條廣播:

  1. public void send(View view) {  
  2.     Intent intent = new Intent(“android.intent.action.MY_BROADCAST”);  
  3.     intent.putExtra(”msg”“hello receiver.”);  
  4.     sendBroadcast(intent);  
  5. }  
    public void send(View view) {
        Intent intent = new Intent("android.intent.action.MY_BROADCAST");
        intent.putExtra("msg", "hello receiver.");
        sendBroadcast(intent);
    }

注意,sendBroadcast也是android.content.ContextWrapper類中的方法,它可以將一個指定地址和參數信息的Intent對象以廣播的形式發送出去。

點擊發送按鈕,執行send方法,控制檯打印如下:


看到這樣的打印信息,表明我們的廣播已經發出去了,並且被MyReceiver準確無誤的接收到了。

上面的例子只是一個接收者來接收廣播,如果有多個接收者都註冊了相同的廣播地址,又會是什麼情況呢,能同時接收到同一條廣播嗎,相互之間會不會有干擾呢?這就涉及到普通廣播和有序廣播的概念了。

普通廣播(Normal Broadcast)

普通廣播對於多個接收者來說是完全異步的,通常每個接收者都無需等待即可以接收到廣播,接收者相互之間不會有影響。對於這種廣播,接收者無法終止廣播,即無法阻止其他接收者的接收動作。

爲了驗證以上論斷,我們新建三個BroadcastReceiver,演示一下這個過程,FirstReceiver、SecondReceiver和ThirdReceiver的代碼如下:

  1. package com.scott.receiver;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.util.Log;  
  7.   
  8. public class FirstReceiver extends BroadcastReceiver {  
  9.       
  10.     private static final String TAG = “NormalBroadcast”;  
  11.       
  12.     @Override  
  13.     public void onReceive(Context context, Intent intent) {  
  14.         String msg = intent.getStringExtra(”msg”);  
  15.         Log.i(TAG, ”FirstReceiver: ” + msg);  
  16.     }  
  17.   
  18. }  
package com.scott.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class FirstReceiver extends BroadcastReceiver {

    private static final String TAG = "NormalBroadcast";

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "FirstReceiver: " + msg);
    }

}
  1. public class SecondReceiver extends BroadcastReceiver {  
  2.       
  3.     private static final String TAG = “NormalBroadcast”;  
  4.       
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         String msg = intent.getStringExtra(”msg”);  
  8.         Log.i(TAG, ”SecondReceiver: ” + msg);  
  9.     }  
  10.   
  11. }  
public class SecondReceiver extends BroadcastReceiver {

    private static final String TAG = "NormalBroadcast";

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "SecondReceiver: " + msg);
    }

}
  1. public class ThirdReceiver extends BroadcastReceiver {  
  2.       
  3.     private static final String TAG = “NormalBroadcast”;  
  4.       
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         String msg = intent.getStringExtra(”msg”);  
  8.         Log.i(TAG, ”ThirdReceiver: ” + msg);  
  9.     }  
  10.   
  11. }  
public class ThirdReceiver extends BroadcastReceiver {

    private static final String TAG = "NormalBroadcast";

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "ThirdReceiver: " + msg);
    }

}
然後再次點擊發送按鈕,發送一條廣播,控制檯打印如下:


看來這三個接收者都接收到這條廣播了,我們稍微修改一下三個接收者,在onReceive方法的最後一行添加以下代碼,試圖終止廣播:

  1. abortBroadcast();  
abortBroadcast();
再次點擊發送按鈕,我們會發現,控制檯中三個接收者仍然都打印了自己的日誌,表明接收者並不能終止廣播。

有序廣播(Ordered Broadcast)

有序廣播比較特殊,它每次只發送到優先級較高的接收者那裏,然後由優先級高的接受者再傳播到優先級低的接收者那裏,優先級高的接收者有能力終止這個廣播。

爲了演示有序廣播的流程,我們修改一下上面三個接收者的代碼,如下:

  1. package com.scott.receiver;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.os.Bundle;  
  7. import android.util.Log;  
  8.   
  9. public class FirstReceiver extends BroadcastReceiver {  
  10.       
  11.     private static final String TAG = “OrderedBroadcast”;  
  12.       
  13.     @Override  
  14.     public void onReceive(Context context, Intent intent) {  
  15.         String msg = intent.getStringExtra(”msg”);  
  16.         Log.i(TAG, ”FirstReceiver: ” + msg);  
  17.           
  18.         Bundle bundle = new Bundle();  
  19.         bundle.putString(”msg”, msg + “@FirstReceiver”);  
  20.         setResultExtras(bundle);  
  21.     }  
  22.   
  23. }  
package com.scott.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class FirstReceiver extends BroadcastReceiver {

    private static final String TAG = "OrderedBroadcast";

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "FirstReceiver: " + msg);

        Bundle bundle = new Bundle();
        bundle.putString("msg", msg + "@FirstReceiver");
        setResultExtras(bundle);
    }

}
  1. public class SecondReceiver extends BroadcastReceiver {  
  2.       
  3.     private static final String TAG = “OrderedBroadcast”;  
  4.       
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         String msg = getResultExtras(true).getString(“msg”);  
  8.         Log.i(TAG, ”SecondReceiver: ” + msg);  
  9.           
  10.         Bundle bundle = new Bundle();  
  11.         bundle.putString(”msg”, msg + “@SecondReceiver”);  
  12.         setResultExtras(bundle);  
  13.     }  
  14.   
  15. }  
public class SecondReceiver extends BroadcastReceiver {

    private static final String TAG = "OrderedBroadcast";

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = getResultExtras(true).getString("msg");
        Log.i(TAG, "SecondReceiver: " + msg);

        Bundle bundle = new Bundle();
        bundle.putString("msg", msg + "@SecondReceiver");
        setResultExtras(bundle);
    }

}
  1. public class ThirdReceiver extends BroadcastReceiver {  
  2.       
  3.     private static final String TAG = “OrderedBroadcast”;  
  4.       
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         String msg = getResultExtras(true).getString(“msg”);  
  8.         Log.i(TAG, ”ThirdReceiver: ” + msg);  
  9.     }  
  10.   
  11. }  
public class ThirdReceiver extends BroadcastReceiver {

    private static final String TAG = "OrderedBroadcast";

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = getResultExtras(true).getString("msg");
        Log.i(TAG, "ThirdReceiver: " + msg);
    }

}
我們注意到,在FirstReceiver和SecondReceiver中最後都使用了setResultExtras方法將一個Bundle對象設置爲結果集對象,傳遞到下一個接收者那裏,這樣以來,優先級低的接收者可以用getResultExtras獲取到最新的經過處理的信息集合。

代碼改完之後,我們需要爲三個接收者註冊廣播地址,我們修改一下AndroidMainfest.xml文件:

  1. <receiver android:name=“.FirstReceiver”>  
  2.     <intent-filter android:priority=“1000”>  
  3.         <action android:name=“android.intent.action.MY_BROADCAST”/>  
  4.         <category android:name=“android.intent.category.DEFAULT” />  
  5.     </intent-filter>  
  6. </receiver>  
  7. <receiver android:name=“.SecondReceiver”>  
  8.     <intent-filter android:priority=“999”>  
  9.         <action android:name=“android.intent.action.MY_BROADCAST”/>  
  10.         <category android:name=“android.intent.category.DEFAULT” />  
  11.     </intent-filter>  
  12. </receiver>  
  13. <receiver android:name=“.ThirdReceiver”>  
  14.     <intent-filter android:priority=“998”>  
  15.         <action android:name=“android.intent.action.MY_BROADCAST”/>  
  16.         <category android:name=“android.intent.category.DEFAULT” />  
  17.     </intent-filter>  
  18. </receiver>  
        <receiver android:name=".FirstReceiver">
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.MY_BROADCAST"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver android:name=".SecondReceiver">
            <intent-filter android:priority="999">
                <action android:name="android.intent.action.MY_BROADCAST"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver android:name=".ThirdReceiver">
            <intent-filter android:priority="998">
                <action android:name="android.intent.action.MY_BROADCAST"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
我們看到,現在這三個接收者的<intent-filter>多了一個android:priority屬性,並且依次減小。這個屬性的範圍在-1000到1000,數值越大,優先級越高。

現在,我們需要修改一下發送廣播的代碼,如下:

  1. public void send(View view) {  
  2.     Intent intent = new Intent(“android.intent.action.MY_BROADCAST”);  
  3.     intent.putExtra(”msg”“hello receiver.”);  
  4.     sendOrderedBroadcast(intent, ”scott.permission.MY_BROADCAST_PERMISSION”);  
  5. }  
    public void send(View view) {
        Intent intent = new Intent("android.intent.action.MY_BROADCAST");
        intent.putExtra("msg", "hello receiver.");
        sendOrderedBroadcast(intent, "scott.permission.MY_BROADCAST_PERMISSION");
    }
注意,使用sendOrderedBroadcast方法發送有序廣播時,需要一個權限參數,如果爲null則表示不要求接收者聲明指定的權限,如果不爲null,則表示接收者若要接收此廣播,需聲明指定權限。這樣做是從安全角度考慮的,例如系統的短信就是有序廣播的形式,一個應用可能是具有攔截垃圾短信的功能,當短信到來時它可以先接受到短信廣播,必要時終止廣播傳遞,這樣的軟件就必須聲明接收短信的權限。

所以我們在AndroidMainfest.xml中定義一個權限:

  1. <permission android:protectionLevel=“normal”  
  2.             android:name=“scott.permission.MY_BROADCAST_PERMISSION” />  
    <permission android:protectionLevel="normal"
                android:name="scott.permission.MY_BROADCAST_PERMISSION" />
然後聲明使用了此權限:

  1. <uses-permission android:name=“scott.permission.MY_BROADCAST_PERMISSION” />  
<uses-permission android:name="scott.permission.MY_BROADCAST_PERMISSION" />

關於這部分如果有不明白的地方可以參考我之前寫過的一篇文章:Android聲明和使用權限

然後我們點擊發送按鈕發送一條廣播,控制檯打印如下:

我們看到接收是按照順序的,第一個和第二個都在結果集中加入了自己的標記,並且向優先級低的接收者傳遞下去。

既然是順序傳遞,試着終止這種傳遞,看一看效果如何,我們修改FirstReceiver的代碼,在onReceive的最後一行添加以下代碼:

  1. abortBroadcast();  
abortBroadcast();
然後再次運行程序,控制檯打印如下:


此次,只有第一個接收者執行了,其它兩個都沒能執行,因爲廣播被第一個接收者終止了。

上面就是BroadcastReceiver的介紹,下面我將會舉幾個常見的例子加深一下大家對廣播的理解和應用:

1.開機啓動服務

我們經常會有這樣的應用場合,比如消息推送服務,需要實現開機啓動的功能。要實現這個功能,我們就可以訂閱系統“啓動完成”這條廣播,接收到這條廣播後我們就可以啓動自己的服務了。我們來看一下BootCompleteReceiver和MsgPushService的具體實現:

  1. package com.scott.receiver;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.util.Log;  
  7.   
  8. public class BootCompleteReceiver extends BroadcastReceiver {  
  9.       
  10.     private static final String TAG = “BootCompleteReceiver”;  
  11.       
  12.     @Override  
  13.     public void onReceive(Context context, Intent intent) {  
  14.         Intent service = new Intent(context, MsgPushService.class);  
  15.         context.startService(service);  
  16.         Log.i(TAG, ”Boot Complete. Starting MsgPushService…”);  
  17.     }  
  18.   
  19. }  
package com.scott.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class BootCompleteReceiver extends BroadcastReceiver {

    private static final String TAG = "BootCompleteReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context, MsgPushService.class);
        context.startService(service);
        Log.i(TAG, "Boot Complete. Starting MsgPushService...");
    }

}
  1. package com.scott.receiver;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.IBinder;  
  6. import android.util.Log;  
  7.   
  8. public class MsgPushService extends Service {  
  9.   
  10.     private static final String TAG = “MsgPushService”;  
  11.       
  12.     @Override  
  13.     public void onCreate() {  
  14.         super.onCreate();  
  15.         Log.i(TAG, ”onCreate called.”);  
  16.     }  
  17.       
  18.     @Override  
  19.     public int onStartCommand(Intent intent, int flags, int startId) {  
  20.         Log.i(TAG, ”onStartCommand called.”);  
  21.         return super.onStartCommand(intent, flags, startId);  
  22.     }  
  23.   
  24.     @Override  
  25.     public IBinder onBind(Intent arg0) {  
  26.         return null;  
  27.     }  
  28. }  
package com.scott.receiver;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MsgPushService extends Service {

    private static final String TAG = "MsgPushService";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate called.");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand called.");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
}
然後我們需要在AndroidManifest.xml中配置相關信息:

  1. <!– 開機廣播接受者 –>  
  2. <receiver android:name=“.BootCompleteReceiver”>  
  3.     <intent-filter>  
  4.         <!– 註冊開機廣播地址–>  
  5.         <action android:name=“android.intent.action.BOOT_COMPLETED”/>  
  6.         <category android:name=“android.intent.category.DEFAULT” />  
  7.     </intent-filter>  
  8. </receiver>  
  9. <!– 消息推送服務 –>  
  10. <service android:name=“.MsgPushService”/>  
        <!-- 開機廣播接受者 -->
        <receiver android:name=".BootCompleteReceiver">
            <intent-filter>
                <!-- 註冊開機廣播地址-->
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <!-- 消息推送服務 -->
        <service android:name=".MsgPushService"/>
我們看到BootCompleteReceiver註冊了“android.intent.action.BOOT_COMPLETED”這個開機廣播地址,從安全角度考慮,系統要求必須聲明接收開機啓動廣播的權限,於是我們再聲明使用下面的權限:

  1. <uses-permission android:name=“android.permission.RECEIVE_BOOT_COMPLETED” />  
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
經過上面的幾個步驟之後,我們就完成了開機啓動的功能,將應用運行在模擬器上,然後重啓模擬器,控制檯打印如下:



如果我們查看已運行的服務就會發現,MsgPushService已經運行起來了。

2.網絡狀態變化

在某些場合,比如用戶瀏覽網絡信息時,網絡突然斷開,我們要及時地提醒用戶網絡已斷開。要實現這個功能,我們可以接收網絡狀態改變這樣一條廣播,當由連接狀態變爲斷開狀態時,系統就會發送一條廣播,我們接收到之後,再通過網絡的狀態做出相應的操作。下面就來實現一下這個功能:

  1. package com.scott.receiver;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.net.ConnectivityManager;  
  7. import android.net.NetworkInfo;  
  8. import android.util.Log;  
  9. import android.widget.Toast;  
  10.   
  11. public class NetworkStateReceiver extends BroadcastReceiver {  
  12.       
  13.     private static final String TAG = “NetworkStateReceiver”;  
  14.       
  15.     @Override  
  16.     public void onReceive(Context context, Intent intent) {  
  17.         Log.i(TAG, ”network state changed.”);  
  18.         if (!isNetworkAvailable(context)) {  
  19.             Toast.makeText(context, ”network disconnected!”0).show();  
  20.         }  
  21.     }  
  22.       
  23.     /** 
  24.      * 網絡是否可用 
  25.      *  
  26.      * @param context 
  27.      * @return 
  28.      */  
  29.     public static boolean isNetworkAvailable(Context context) {  
  30.         ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  
  31.         NetworkInfo[] info = mgr.getAllNetworkInfo();  
  32.         if (info != null) {  
  33.             for (int i = 0; i < info.length; i++) {  
  34.                 if (info[i].getState() == NetworkInfo.State.CONNECTED) {  
  35.                     return true;  
  36.                 }  
  37.             }  
  38.         }  
  39.         return false;  
  40.     }  
  41.   
  42. }  
package com.scott.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import android.widget.Toast;

public class NetworkStateReceiver extends BroadcastReceiver {

    private static final String TAG = "NetworkStateReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "network state changed.");
        if (!isNetworkAvailable(context)) {
            Toast.makeText(context, "network disconnected!", 0).show();
        }
    }

    /**
     * 網絡是否可用
     * 
     * @param context
     * @return
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo[] info = mgr.getAllNetworkInfo();
        if (info != null) {
            for (int i = 0; i < info.length; i++) {
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
            }
        }
        return false;
    }

}
再註冊一下這個接收者的信息:

  1. <receiver android:name=“.NetworkStateReceiver”>  
  2.     <intent-filter>  
  3.         <action android:name=“android.net.conn.CONNECTIVITY_CHANGE”/>  
  4.         <category android:name=“android.intent.category.DEFAULT” />  
  5.     </intent-filter>  
  6. </receiver>  
        <receiver android:name=".NetworkStateReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
因爲在isNetworkAvailable方法中我們使用到了網絡狀態相關的API,所以需要聲明相關的權限才行,下面就是對應的權限聲明:

  1. <uses-permission android:name=“android.permission.ACCESS_NETWORK_STATE”/>  
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
我們可以測試一下,比如關閉WiFi,看看有什麼效果。

3.電量變化

如果我們閱讀軟件,可能是全屏閱讀,這個時候用戶就看不到剩餘的電量,我們就可以爲他們提供電量的信息。要想做到這一點,我們需要接收一條電量變化的廣播,然後獲取百分比信息,這聽上去挺簡單的,我們就來實現以下:

  1. package com.scott.receiver;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.os.BatteryManager;  
  7. import android.util.Log;  
  8.   
  9. public class BatteryChangedReceiver extends BroadcastReceiver {  
  10.   
  11.     private static final String TAG = “BatteryChangedReceiver”;  
  12.       
  13.     @Override  
  14.     public void onReceive(Context context, Intent intent) {  
  15.         int currLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);  //當前電量  
  16.         int total = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);      //總電量  
  17.         int percent = currLevel * 100 / total;  
  18.         Log.i(TAG, ”battery: ” + percent + “%”);  
  19.     }  
  20.   
  21. }  
package com.scott.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.BatteryManager;
import android.util.Log;

public class BatteryChangedReceiver extends BroadcastReceiver {

    private static final String TAG = "BatteryChangedReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        int currLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);  //當前電量
        int total = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);      //總電量
        int percent = currLevel * 100 / total;
        Log.i(TAG, "battery: " + percent + "%");
    }

}
然後再註冊一下廣播接地址信息就可以了:

  1. <receiver android:name=“.BatteryChangedReceiver”>  
  2.     <intent-filter>  
  3.         <action android:name=“android.intent.action.BATTERY_CHANGED”/>  
  4.         <category android:name=“android.intent.category.DEFAULT” />  
  5.     </intent-filter>  
  6. </receiver>  
        <receiver android:name=".BatteryChangedReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BATTERY_CHANGED"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

當然,有些時候我們是要立即獲取電量的,而不是等電量變化的廣播,比如當閱讀軟件打開時立即顯示出電池電量。我們可以按以下方式獲取:

  1. Intent batteryIntent = getApplicationContext().registerReceiver(null,  
  2.         new IntentFilter(Intent.ACTION_BATTERY_CHANGED));  
  3. int currLevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);  
  4. int total = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);  
  5. int percent = currLevel * 100 / total;  
  6. Log.i(”battery”“battery: ” + percent + “%”);  
Intent batteryIntent = getApplicationContext().registerReceiver(null,
        new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int currLevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int total = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
int percent = currLevel * 100 / total;
Log.i("battery", "battery: " + percent + "%");

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章