Android BroadcastReceiver使用詳解

在 Android 系統中,廣播(Broadcast)是在組件之間傳播數據的一種機制,這些組件能夠位於不一樣的進程中,起到進程間通訊的做用android

BroadcastReceiver 是對發送出來的 Broadcast 進行過濾、接受和響應的組件。首先將要發送的消息和用於過濾的信息(Action,Category)裝入一個 Intent 對象,而後經過調用 Context.sendBroadcast()sendOrderBroadcast() 方法把 Intent 對象以廣播形式發送出去。 廣播發送出去後,因此已註冊的 BroadcastReceiver 會檢查註冊時的 IntentFilter 是否與發送的 Intent 相匹配,若匹配則會調用 BroadcastReceiver 的 onReceiver() 方法git

因此當咱們定義一個 BroadcastReceiver 的時候,都須要實現 onReceiver() 方法。BroadcastReceiver 的生命週期很短,在執行 onReceiver() 方法時纔有效,一旦執行完畢,該Receiver 的生命週期就結束了github

Android中的廣播分爲兩種類型,標準廣播和有序廣播緩存

  • 標準廣播 標準廣播是一種徹底異步執行的廣播,在廣播發出後全部的廣播接收器會在同一時間接收到這條廣播,之間沒有前後順序,效率比較高,且沒法被截斷
  • 有序廣播 有序廣播是一種同步執行的廣播,在廣播發出後同一時刻只有一個廣播接收器可以接收到, 優先級高的廣播接收器會優先接收,當優先級高的廣播接收器的 onReceiver() 方法運行結束後,廣播纔會繼續傳遞,且前面的廣播接收器能夠選擇截斷廣播,這樣後面的廣播接收器就沒法接收到這條廣播了

1、靜態註冊

靜態註冊即在清單文件中爲 BroadcastReceiver 進行註冊,使用**< receiver >**標籤聲明,並在標籤內用 < intent-filter > 標籤設置過濾器。這種形式的 BroadcastReceiver 的生命週期伴隨着整個應用,若是這種方式處理的是系統廣播,那麼無論應用是否在運行,該廣播接收器都能接收到該廣播安全

1.一、發送標準廣播

首先,繼承 BroadcastReceiver 類建立一個用於接收標準廣播的Receiver,在 onReceive() 方法中取出 Intent 傳遞來的字符串bash

public class NormalReceiver extends BroadcastReceiver {

    private static final String TAG = "NormalReceiver";

    public NormalReceiver() {
    }

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

}
複製代碼

在清單文件中聲明的 BroadcastReceiver ,必須包含值爲 NORMAL_ACTION 字符串的 action 屬性,該廣播接收器才能收到如下代碼中發出的廣播網絡

發送標準廣播調用的是 sendBroadcast(Intent) 方法app

public class MainActivity extends AppCompatActivity {

    private final String NORMAL_ACTION = "com.example.normal.receiver";

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

    public void sendBroadcast(View view) {
        Intent intent = new Intent(NORMAL_ACTION);
        intent.putExtra("Msg", "Hi");
        sendBroadcast(intent);
    }

}
複製代碼

在清單文件中註冊 BroadcastReceiver異步

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".NormalReceiver">
            <intent-filter>
                <action android:name="com.example.normal.receiver" />
            </intent-filter>
        </receiver>
        
    </application>
複製代碼

1.二、發送有序廣播

首先,繼承 BroadcastReceiver 類建立三個用於接收有序廣播的Receiver,名字依次命名爲 OrderReceiver_一、OrderReceiver_二、OrderReceiver_3。此外,既然 Receiver 在接收廣播時存在前後順序,那麼 Receiver 除了能從發送廣播使用的 Intent 接收數據外,優先級高的 Receiver 也能在處理完操做後向優先級低的 Receiver 傳送處理結果ide

public class OrderReceiver_1 extends BroadcastReceiver {

    private final String TAG = "OrderReceiver_1";

    public OrderReceiver_1() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e(TAG, "OrderReceiver_1被調用了");

        //取出Intent當中傳遞來的數據
        String msg = intent.getStringExtra("Msg");
        Log.e(TAG, "OrderReceiver_1接收到的值: " + msg);

        //向下一優先級的Receiver傳遞數據
        Bundle bundle = new Bundle();
        bundle.putString("Data", "(Hello)");
        setResultExtras(bundle);
    }
}
複製代碼
public class OrderReceiver_2 extends BroadcastReceiver {

    private final String TAG = "OrderReceiver_2";

    public OrderReceiver_2() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e(TAG, "OrderReceiver_2被調用了");

        //取出上一優先級的Receiver傳遞來的數據
        String data = getResultExtras(true).getString("Data");
        Log.e(TAG, "從上一優先級的Receiver傳遞來的數據--" + data);

        //向下一優先級的Receiver傳遞數據
        Bundle bundle = new Bundle();
        bundle.putString("Data", "(葉應是葉)");
        setResultExtras(bundle);
    }
}
複製代碼
public class OrderReceiver_3 extends BroadcastReceiver {

    private final String TAG = "OrderReceiver_3";

    public OrderReceiver_3() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e(TAG, "OrderReceiver_3被調用了");

        //取出上一優先級的Receiver傳遞來的數據
        String data = getResultExtras(true).getString("Data");
        Log.e(TAG, "從上一優先級的Receiver傳遞來的數據--" + data);
    }
}
複製代碼

在清單文件中對三個 Receiver 進行註冊,指定相同的 action 屬性值,Receiver 之間的優先級使用 priority 屬性來斷定,數值越大,優先級越高

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

		
        <receiver android:name=".OrderReceiver_1">
            <intent-filter android:priority="100">
                <action android:name="com.example.order.receiver" />
            </intent-filter>
        </receiver>
		
        <receiver android:name=".OrderReceiver_2">
            <intent-filter android:priority="99">
                <action android:name="com.example.order.receiver" />
            </intent-filter>
        </receiver>
		
        <receiver android:name=".OrderReceiver_3">
            <intent-filter android:priority="98">
                <action android:name="com.example.order.receiver" />
            </intent-filter>
        </receiver>
		
    </application>
複製代碼

發送有序廣播調用的是 sendOrderedBroadcast(Intent , String) 方法,String 參數值在自定義權限時使用,下邊會有介紹

public class MainActivity extends AppCompatActivity {

    private final String NORMAL_ACTION = "com.example.normal.receiver";

    private final String ORDER_ACTION = "com.example.order.receiver";

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

    public void sendBroadcast(View view) {
        Intent intent = new Intent(NORMAL_ACTION);
        intent.putExtra("Msg", "Hi");
        sendBroadcast(intent);
    }

    public void sendOrderBroadcast(View view) {
        Intent intent = new Intent(ORDER_ACTION);
        intent.putExtra("Msg", "Hi");
        sendOrderedBroadcast(intent, null);
    }

}
複製代碼

運行結果是

02-20 22:52:30.135 6714-6714/com.example.zy.myapplication E/OrderReceiver_1: OrderReceiver_1被調用了
02-20 22:52:30.135 6714-6714/com.example.zy.myapplication E/OrderReceiver_1: OrderReceiver_1接收到的值: Hi
02-20 22:52:30.143 6714-6714/com.example.zy.myapplication E/OrderReceiver_2: OrderReceiver_2被調用了
02-20 22:52:30.143 6714-6714/com.example.zy.myapplication E/OrderReceiver_2: 從上一優先級的Receiver傳遞來的數據--(Hello)
02-20 22:52:30.150 6714-6714/com.example.zy.myapplication E/OrderReceiver_3: OrderReceiver_3被調用了
02-20 22:52:30.150 6714-6714/com.example.zy.myapplication E/OrderReceiver_3: 從上一優先級的Receiver傳遞來的數據--(葉應是葉)
複製代碼

能夠看出 Receiver 接收廣播時不只由於「priority」屬性存在前後順序,且 Receiver 之間也可以傳遞數據

此外,BroadcastReceiver 也能調用 abortBroadcast() 方法截斷廣播,這樣低優先級的廣播接收器就沒法接收到廣播了

2、動態註冊

動態註冊 BroadcastReceiver 是在代碼中定義並設置好一個 IntentFilter 對象,而後在須要註冊的地方調用 Context.registerReceiver() 方法,調用 Context.unregisterReceiver() 方法取消註冊,此時就不須要在清單文件中註冊 Receiver 了

這裏採用在 Service 中註冊廣播接收器的形式,分別在註冊廣播接收器取消註冊廣播接受器接收到廣播時輸出Log

public class BroadcastService extends Service {

    private BroadcastReceiver receiver;

    private final String TAG = "BroadcastService";

    public BroadcastService() {
    }

    @Override
    public void onCreate() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(MainActivity.ACTION);
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.e(TAG, "BroadcastService接收到了廣播");
            }
        };
        registerReceiver(receiver, intentFilter);
        Log.e(TAG, "BroadcastService註冊了接收器");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
        Log.e(TAG, "BroadcastService取消註冊接收器");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}
複製代碼

提供啓動服務,中止服務、發送廣播的方法

public class MainActivity extends AppCompatActivity {

    public final static String ACTION = "com.example.receiver";

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

    public void startService(View view) {
        Intent intent = new Intent(this, BroadcastService.class);
        startService(intent);
    }

    public void sendBroadcast(View view) {
        Intent intent = new Intent(ACTION);
        sendBroadcast(intent);
    }

    public void stopService(View view) {
        Intent intent = new Intent(this, BroadcastService.class);
        stopService(intent);
    }

}

複製代碼

運行結果以下所示

02-20 23:55:20.967 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService註冊了接收器
02-20 23:55:22.811 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService接收到了廣播
02-20 23:55:23.179 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService接收到了廣播
02-20 23:55:23.461 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService接收到了廣播
02-20 23:55:23.694 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService接收到了廣播
02-20 23:55:23.960 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService接收到了廣播
02-20 23:55:24.282 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService接收到了廣播
02-20 23:55:24.529 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService接收到了廣播
02-20 23:55:24.916 22784-22784/com.example.zy.myapplication E/BroadcastService: BroadcastService取消註冊接收器
複製代碼

3、本地廣播

以前發送和接收到的廣播全都是屬於系統全局廣播,即發出的廣播能夠被其餘應用接收到,並且也能夠接收到其餘應用發送出的廣播,這樣可能會有不安全因素

所以,在某些狀況下能夠採用本地廣播機制,使用這個機制發出的廣播只能在應用內部進行傳遞,並且廣播接收器也只能接收本應用內自身發出的廣播

本地廣播是使用 LocalBroadcastManager 來對廣播進行管理

函數 做用
LocalBroadcastManager.getInstance(this).registerReceiver(BroadcastReceiver, IntentFilter) 註冊Receiver
LocalBroadcastManager.getInstance(this).unregisterReceiver(BroadcastReceiver); 註銷Receiver
LocalBroadcastManager.getInstance(this).sendBroadcast(Intent) 發送異步廣播
LocalBroadcastManager.getInstance(this).sendBroadcastSync(Intent) 發送同步廣播

首先,建立一個 BroadcastReceiver 用於接收本地廣播

public class LocalReceiver extends BroadcastReceiver {

    private final String TAG = "LocalReceiver";

    public LocalReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e(TAG, "接收到了本地廣播");
    }
    
}
複製代碼

以後就是使用 LocalBroadcastManager 對 LocalReceiver 進行註冊和解除註冊了

private LocalBroadcastManager localBroadcastManager;

    private LocalReceiver localReceiver;

    private final String LOCAL_ACTION = "com.example.local.receiver";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        localReceiver = new LocalReceiver();
        IntentFilter filter = new IntentFilter(LOCAL_ACTION);
        localBroadcastManager.registerReceiver(localReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(batteryReceiver);
        localBroadcastManager.unregisterReceiver(localReceiver);
    }
	
	public void sendLocalBroadcast(View view) {
        Intent intent = new Intent(LOCAL_ACTION);
        localBroadcastManager.sendBroadcast(intent);
    }

複製代碼

須要注意的是,本地廣播是沒法經過靜態註冊的方式來接收的,由於靜態註冊廣播主要是爲了在程序未啓動的狀況下也能接收廣播,而本地廣播是應用本身發送的,此時應用確定是啓動的了

4、使用私有權限

使用動態註冊廣播接收器存在一個問題,即系統內的任何應用都可監聽並觸發咱們的 Receiver 。一般狀況下咱們是不但願如此的

解決辦法之一是在清單文件中爲 < receiver > 標籤添加一個 android:exported="false" 屬性,標明該 Receiver 僅限應用內部使用。這樣,系統中的其餘應用就沒法接觸到該 Receiver 了

此外,也能夠選擇建立本身的使用權限,即在清單文件中添加一個 < permission > 標籤來聲明自定義權限

<permission
        android:name="com.example.permission.receiver"
        android:protectionLevel="signature" />
複製代碼

自定義權限時必須同時指定 protectionLevel 屬性值,系統根據該屬性值肯定自定義權限的使用方式

屬性值 限定方式
normal 默認值。較低風險的權限,對其餘應用,系統和用戶來講風險最小。系統在安裝應用時會自動批准授予應用該類型的權限,不要求用戶明確批准(雖然用戶在安裝以前老是能夠選擇查看這些權限)
dangerous 較高風險的權限,請求該類型權限的應用程序會訪問用戶私有數據或對設備進行控制,從而可能對用戶形成負面影響。由於這種類型的許可引入了潛在風險,因此係統可能不會自動將其授予請求的應用。例如,系統能夠向用戶顯示由應用請求的任何危險許可,而且在繼續以前須要確認,或者能夠採起一些其餘方法來避免用戶自動容許
signature 只有在請求該權限的應用與聲明權限的應用使用相同的證書籤名時,系統纔會授予權限。若是證書匹配,系統會自動授予權限而不通知用戶或要求用戶的明確批准
signatureOrSystem 系統僅授予Android系統映像中與聲明權限的應用使用相同的證書籤名的應用。請避免使用此選項,「signature」級別足以知足大多數需求,「signatureOrSystem」權限用於某些特殊狀況

首先,新建一個新的工程,在它的清單文件中建立一個自定義權限,並聲明該權限。protectionLevel 屬性值設爲「signature

<permission
        android:name="com.example.permission.receiver"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.example.permission.receiver" />
複製代碼

而後,發送含有該權限聲明的 Broadcast 。這樣,只有使用相同證書籤名且聲明該權限的應用才能接收到該 Broadcast 了

private final String PERMISSION_PRIVATE = "com.example.permission.receiver";

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

    public void sendPermissionBroadcast(View view) {
        sendBroadcast(new Intent("Hi"), PERMISSION_PRIVATE);
    }
複製代碼

回到以前的工程 首先在清單文件中聲明權限

<uses-permission android:name="com.example.permission.receiver" />
複製代碼

建立一個 BroadcastReceiver

public class PermissionReceiver extends BroadcastReceiver {

    private final String TAG = "PermissionReceiver";

    public PermissionReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e(TAG, "接收到了私有權限廣播");
    }
}
複製代碼

而後註冊廣播接收器。由於 Android Studio 在調試的時候會使用相同的證書爲每一個應用簽名,因此,在以前新安裝的App發送出廣播後,PermissionReceiver 就會輸出 Log 日誌

private final String PERMISSION_PRIVATE = "com.example.permission.receiver";

    private PermissionReceiver permissionReceiver;

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

        IntentFilter intentFilter1 = new IntentFilter("Hi");
        permissionReceiver = new PermissionReceiver();
        registerReceiver(permissionReceiver, intentFilter1, PERMISSION_PRIVATE, null);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(permissionReceiver);
    }
複製代碼

5、實戰演練

5.一、監聽網絡狀態變化

首先須要一個用來監測當前網絡狀態的工具類

/**
 * Created by 葉應是葉 on 2017/2/21.
 */

public class NetworkUtils {

    /**
     * 標記當前網絡狀態,分別是:移動數據、Wifi、未鏈接、網絡狀態已公佈
     */
    public enum State {
        MOBILE, WIFI, UN_CONNECTED, PUBLISHED
    }

    /**
     * 爲了不因屢次接收到廣播反覆提醒的狀況而設置的標誌位,用於緩存收到新的廣播前的網絡狀態
     */
    private static State tempState;

    /**
     * 獲取當前網絡鏈接狀態
     *
     * @param context Context
     * @return 網絡狀態
     */
    public static State getConnectState(Context context) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        State state = State.UN_CONNECTED;
        if (networkInfo != null && networkInfo.isAvailable()) {
            if (isMobileConnected(context)) {
                state = State.MOBILE;
            } else if (isWifiConnected(context)) {
                state = State.WIFI;
            }
        }
        if (state.equals(tempState)) {
            return State.PUBLISHED;
        }
        tempState = state;
        return state;
    }

    private static boolean isMobileConnected(Context context) {
        return isConnected(context, ConnectivityManager.TYPE_MOBILE);
    }

    private static boolean isWifiConnected(Context context) {
        return isConnected(context, ConnectivityManager.TYPE_WIFI);
    }

    private static boolean isConnected(Context context, int type) {
        //getAllNetworkInfo() 在 API 23 中被棄用
        //getAllNetworks() 在 API 21 中才添加
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            NetworkInfo[] allNetworkInfo = manager.getAllNetworkInfo();
            for (NetworkInfo info : allNetworkInfo) {
                if (info.getType() == type) {
                    return info.isAvailable();
                }
            }
        } else {
            Network[] networks = manager.getAllNetworks();
            for (Network network : networks) {
                NetworkInfo networkInfo = manager.getNetworkInfo(network);
                if (networkInfo.getType() == type) {
                    return networkInfo.isAvailable();
                }
            }
        }
        return false;
    }

}
複製代碼

而後聲明一個 BroadcastReceiver ,在onReceive() 方法中用Log輸出當前網絡狀態

public class NetworkReceiver extends BroadcastReceiver {

    private static final String TAG = "NetworkReceiver";

    public NetworkReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        switch (NetworkUtils.getConnectState(context)) {
            case MOBILE:
                Log.e(TAG, "當前鏈接了移動數據");
                break;
            case WIFI:
                Log.e(TAG, "當前鏈接了Wifi");
                break;
            case UN_CONNECTED:
                Log.e(TAG, "當前沒有網絡鏈接");
                break;
        }
    }

}
複製代碼

在清單文件中註冊廣播接收器,「android.net.conn.CONNECTIVITY_CHANGE」是系統預約義好的 action 值,只要系統網絡狀態發生變化,NetworkReceiver 就能收到廣播

<receiver android:name=".NetworkReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
複製代碼

此外,還要申請查看網絡狀態的權限

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
複製代碼

5.二、監聽電量變化

由於系統規定監聽電量變化的廣播接收器不能靜態註冊,因此這裏只能使用動態註冊的方式了

private final String TAG = "MainActivity";

    private BroadcastReceiver batteryReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
        batteryReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // 當前電量
                int currentBattery = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
                // 總電量
                int totalBattery = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);         
                Log.e(TAG, "當前電量:" + currentBattery + "-總電量:" + totalBattery);
            }
        };
        registerReceiver(batteryReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(batteryReceiver);
    }
複製代碼

onReceive(Context , Intent ) 中的 Intent 值包含了一些額外信息,能夠取出當前電量和總電量

爲了方便查看電量變化,能夠在模擬器的「extended controls」面板中主動地改變模擬器的電量,查看Log輸出

這裏寫圖片描述

5.三、應用安裝更新卸載監聽

首先,建立 BroadcastReceiver

public class AppReceiver extends BroadcastReceiver {

    private final String TAG = "AppReceiver";

    public AppReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        //判斷廣播類型
        String action = intent.getAction();
        //獲取包名
        Uri appName = intent.getData();
        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
            Log.e(TAG, "安裝了:" + appName);
        } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
            Log.e(TAG, "更新了:" + appName);
        } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
            Log.e(TAG, "卸載了:" + appName);
        }
    }
}

複製代碼

註冊廣播接收器

<receiver android:name=".train.AppReceiver">
            <intent-filter>
                <!--安裝應用-->
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <!--更新應用-->
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <!--卸載應用-->
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <!--攜帶包名-->
                <data android:scheme="package" />
            </intent-filter>
        </receiver>
複製代碼

這裏提供本文章全部示例代碼下載:Android BroadcastReceiver使用詳解

相關文章
相關標籤/搜索