Android BroadCastReceiver 二

01.监听网络状态变化

  • 写一个监听网络状态变化工具类

    • 首先需要一个用来监测当前网络状态的工具类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    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 = null;
    if (manager != null) {
    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 = new NetworkInfo[0];
    if (manager != null) {
    allNetworkInfo = manager.getAllNetworkInfo();
    }
    for (NetworkInfo info : allNetworkInfo) {
    if (info.getType() == type) {
    return info.isAvailable();
    }
    }
    } else {
    Network[] networks = new Network[0];
    if (manager != null) {
    networks = manager.getAllNetworks();
    }
    for (Network network : networks) {
    NetworkInfo networkInfo = manager.getNetworkInfo(network);
    if (networkInfo.getType() == type) {
    return networkInfo.isAvailable();
    }
    }
    }
    return false;
    }
    }
  • 然后声明一个 BroadcastReceiver ,在onReceive() 方法中用Log输出当前网络状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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:
    LogUtils.i(TAG+"当前连接了移动数据");
    break;
    case WIFI:
    LogUtils.i(TAG+ "当前连接了Wifi");
    break;
    case UN_CONNECTED:
    LogUtils.i(TAG+ "当前没有网络连接");
    break;
    default:
    LogUtils.i(TAG+ "其他情况");
    break;
    }
    }
    }
  • 在清单文件中注册广播接收器,“android.net.conn.CONNECTIVITY_CHANGE”是系统预定义好的 action 值,只要系统网络状态发生变化,NetworkReceiver 就能收到广播

    1
    2
    3
    4
    5
    <receiver android:name=".NetworkReceiver">
    <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
    </receiver>
    • 此外,还要申请查看网络状态的权限
    1
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • 注册与解绑广播操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private NetworkReceiver receiver;
    private void test(){
    receiver = new NetworkReceiver();
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
    registerReceiver(receiver, intentFilter);
    LogUtils.i("广播NetworkReceiver------BroadcastService注册了接收器");
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    if (receiver!=null){
    unregisterReceiver(receiver);
    LogUtils.i("广播NetworkReceiver------BroadcastService取消注册接收器");
    }
    }
  • 测试结果

    1
    2
    3
    4
    5
    6
    2019-06-21 13:34:09.476 1653-1653/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------BroadcastService注册了接收器
    2019-06-21 13:34:09.485 1653-1653/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------当前连接了Wifi
    2019-06-21 13:34:14.320 1653-1653/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------当前没有网络连接
    2019-06-21 13:34:29.216 1653-1653/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------当前连接了Wifi
    2019-06-21 13:34:36.838 1653-1653/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------当前没有网络连接
    2019-06-21 13:34:43.617 1653-1653/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------BroadcastService取消注册接收器

02.监听电量变化

  • 因为系统规定监听电量变化的广播接收器不能静态注册,所以这里只能使用动态注册的方式了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    /**
    * 电池状态即电量变化广播接收器
    */
    private BroadcastReceiver mBatterReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
    int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
    BatteryManager.BATTERY_STATUS_UNKNOWN);
    if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
    // 充电中
    LogUtils.i("广播NetworkReceiver------充电中");
    } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
    // 充电完成
    LogUtils.i("广播NetworkReceiver------充电完成");
    } else {
    // 当前电量
    int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
    // 总电量
    int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
    int percentage = (int) (((float) level / scale) * 100);
    LogUtils.i("广播NetworkReceiver------当前电量"+level);
    LogUtils.i("广播NetworkReceiver------总电量"+scale);
    LogUtils.i("广播NetworkReceiver------百分比"+percentage);
    }
    }
    };
    • onReceive(Context , Intent ) 中的 Intent 值包含了一些额外信息,可以取出当前电量和总电量。为了方便查看电量变化,可以在模拟器的“extended controls”面板中主动地改变模拟器的电量,查看Log输出
  • 广播的注册和解绑操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    private void test(){
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
    registerReceiver(mBatterReceiver, intentFilter);
    LogUtils.i("广播NetworkReceiver------BroadcastService注册了接收器");
    }


    @Override
    public void onDestroy() {
    super.onDestroy();
    if (mBatterReceiver!=null){
    unregisterReceiver(mBatterReceiver);
    LogUtils.i("广播NetworkReceiver------BroadcastService取消注册接收器");
    }
    }
  • 测试结果

    1
    2
    3
    4
    5
    6
    2019-06-21 13:47:38.581 3182-3182/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------BroadcastService注册了接收器
    2019-06-21 13:47:38.583 3182-3182/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------当前电量100
    2019-06-21 13:47:38.584 3182-3182/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------总电量100
    2019-06-21 13:47:38.585 3182-3182/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------百分比100
    2019-06-21 13:47:54.658 3182-3182/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------充电完成
    2019-06-21 13:48:08.161 3182-3182/com.ycbjie.other I/TestActivity: │ 广播NetworkReceiver------BroadcastService取消注册接收器

03.应用安装更新卸载监听

  • 首先,创建 BroadcastReceiver

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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);
    }
    }
    }
  • 注册广播接收器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <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>