Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

第 46 章 消息廣播

目錄

46.1. 動態註冊
46.2. 靜態註冊
46.3. 自定義用戶消息廣播
46.4. 本地廣播

安卓中有兩種廣播,一種是系統發出的廣播信息,例如網絡改變,電池的電量低等等,另一種是用戶發出的廣播信息。

Android 中的廣播類型可以分為兩種類型,標準廣播和有序廣播。

標準廣播(Normal broadcasts):標準廣播是一種完全非同步執行的廣播,在廣播發出之後,所有的廣播接收器几乎會在同一時刻接收到這條廣播消息。這種廣播效率比較高,但同時也意味着它是無法被截斷的。

有序廣播(Ordered broadcasts):有序廣播則是一種同步執行的廣播,在廣播發出之後,同一時刻只會有一個廣播接收器能夠收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢之後,廣播才會繼續傳遞。

	
android.intent.action.BATTERY_CHANGED	持久廣播含充電狀態,級別,以及其他相關的電池信息。
android.intent.action.BATTERY_LOW		顯示設備的電池電量低。
android.intent.action.BATTERY_OKAY		指示電池正在低點後但沒有問題。
android.intent.action.BOOT_COMPLETED	一次播出後,系統已完成啟動。
android.intent.action.BUG_REPORT		顯示活動報告的錯誤。
android.intent.action.CALL				執行呼叫由數據指定某人。
android.intent.action.CALL_BUTTON		用戶按下“呼叫”按鈕進入撥號器或其他適當的用戶界面發出呼叫。
android.intent.action.DATE_CHANGED		日期改變。
android.intent.action.REBOOT			有設備重啟。	
	
	

46.1. 動態註冊

		
package cn.netkiller.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private MyBroadcastReceiver myBroadcastReceiver;

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

        intentFilter = new IntentFilter();
        //為過濾器添加處理規則
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        myBroadcastReceiver = new MyBroadcastReceiver();
        //註冊廣播接收器
        registerReceiver(myBroadcastReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //註銷動態的廣播接收器
        unregisterReceiver(myBroadcastReceiver);
    }

    //自定義內部類,繼承 BroadcastReceiver
    public class MyBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "網絡狀態已改變", Toast.LENGTH_SHORT).show();
        }
    }
}
		
		
		

現在嘗試改變網絡狀態,例如開啟或關閉飛行模式,程序會彈出 "網絡狀態已改變"。

我的測試環境是 Android 9 Pie 沒有加入下面的權限仍然能工作

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

優化程序

		
package cn.netkiller.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.BatteryManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private MyBroadcastReceiver myBroadcastReceiver;

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

        intentFilter = new IntentFilter();
        //為過濾器添加處理規則
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
        intentFilter.addAction(Intent.ACTION_BATTERY_LOW);

        myBroadcastReceiver = new MyBroadcastReceiver();
        //註冊廣播接收器
        registerReceiver(myBroadcastReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //註銷動態的廣播接收器
        unregisterReceiver(myBroadcastReceiver);
    }

    //自定義內部類,繼承 BroadcastReceiver
    public class MyBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            //判斷是否聯網
            if (networkInfo != null && networkInfo.isConnected()) {
                Toast.makeText(context, "網絡已連接", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "網絡不可用", Toast.LENGTH_SHORT).show();
            }

            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                    status == BatteryManager.BATTERY_STATUS_FULL;

            if (isCharging) {
                Toast.makeText(context, "正在充電", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "電池已經充滿", Toast.LENGTH_SHORT).show();
            }

            int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
            boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
            boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
            if (usbCharge) {
                Toast.makeText(context, "USB 充電", Toast.LENGTH_SHORT).show();
            }

        }
    }
}