iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 26
0
自我挑戰組

Android初學筆記系列 第 26

Day 26 - BroadcastReceiver接收事件

BrocastReceiver是個廣播接收元件,當系統發生一些事情如連接網路、開始充電、重新開機時,BroadcastRecaiver會有所反應並讓我們做相應的處理。

BroadcastReceiver可以在Activity內運作也可以獨立運作,例如當使用者在Activity中時我想知道現在有無網路,就為此Activity註冊一個BroadcatReceiver來接收網路連線事件。若是系統相關的例如裝置重新開機,此時畫面必定不是在我們的Activity上,就可以為整個APP註冊一個獨立的BroadcastReceiver來監聽。

Activity中檢查網路連線

我們為Activity註冊一個BroadcastReceiver,接收使用者開啟或關閉網路的事件

在AndroidManifest.xml中加入權限

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

Java程式碼

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onResume()
    {
        super.onResume();
        // 註冊mConnReceiver,並用IntentFilter設置接收的事件類型為網路開關
        this.registerReceiver(mConnReceiver,
                new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
    }

    @Override
    public void onPause()
    {
        super.onPause();
        // 解除註冊
        this.unregisterReceiver(mConnReceiver);
    }

    // 建立一個BroadcastReceiver,名為mConnReceiver
    private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // 當使用者開啟或關閉網路時會進入這邊

            // 判斷目前有無網路
            if(isNetworkAvailable()) {
                // 以連線至網路,做更新資料等事情
                Toast.makeText(MainActivity.this, "有網路!", Toast.LENGTH_SHORT).show();
            }
            else {
                // 沒有網路
                Toast.makeText(MainActivity.this, "沒網路!", Toast.LENGTH_SHORT).show();
            }
        }
    };

    // 回傳目前是否已連線至網路
    public boolean isNetworkAvailable()
    {
        ConnectivityManager cm = 
            (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();

        return networkInfo != null &&
                networkInfo.isConnected();
    }
}

在onResume中註冊並在onStop解除註冊,因為當使用者離開頁面時我們不用再判斷是否有網路,等他返回時再開始判斷就好。

註冊時的IntentFilter就是指定我們的BroadcastReceiver要接收哪種事件,使用CONNECTIVITY_ACTION接收使用者開關網路事件,這樣當每次開關網路時就會進入onReceive中,我們再判斷是否有網路並做處理。

開關網路事件並不限於Wifi或行動網路,不管開或關哪個都會執行onReceive,若想進一步判斷目前連線是否為Wifi就將isNetworkAvailable的回傳改成

return networkInfo != null &&
       networkInfo.isConnected() &&
       networkInfo.getType() == ConnectivityManager.TYPE_WIFI;

執行APP,開關網路時就會顯示訊息囉
http://ithelp.ithome.com.tw/upload/images/20170110/20103849PBtwCAcm5U.png


獨立的BroadcastReceiver

建立一個獨立運作的BroadcastReceiver跟建立Activity的方式雷同,先建一個新的Java class,內容如下

public class MyBroadcastReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        // 接收到事件時要做的事,要接收哪種事件則寫在AndroidManifest裡
        
    }
}

在AndroidManifest.xml中加入BroadcastReceiver,用intent-filter設定要接收的事件,此處接收AIRPLANE_MODE所以會在開或關飛航模式時進入onReceive

<receiver
    android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.AIRPLANE_MODE" />
    </intent-filter>
</receiver>

http://ithelp.ithome.com.tw/upload/images/20170110/20103849cg4afuHl3q.png

這樣就完成囉


Android 7.0開始因為系統省電考量,獨立的BroadcastReceiver無法接收CONNECTIVITY_CHANGE(網路開關)事件,若有這個需求的話須改用JobScheduler等方式完成,可以參考Android Developers說明進一步了解。


上一篇
Day 25 - 使用Picasso讀取圖片
下一篇
Day 27 - Parcelable物件
系列文
Android初學筆記30

尚未有邦友留言

立即登入留言