Android 四大组件 之 BroadcastReceiver(广播接收者)

BroadcastReceiver(广播接收者) 简介

  • BroadcastReceiver(广播接收者) 属于 Android 四大组件中的第三个
  • BroadcastReceiver 官方对应文档地址:http://androiddoc.qiniudn.com/reference/android/content/BroadcastReceiver.html
  • 举个例子:学校读书的时候,学校通常都会有一个大喇叭,用来广播一些通知,比如开学要去搬书的时候,学校会广播: "每个班级找几个同学教务处拿书",发出这个广播后,所有同学都会在同一时刻收到这条广播通知, 于是班级里面会派人一般去搬书回来。大喇叭--> 发送广播 --> 所有学生都能收到广播 --> 学生去搬书(处理广播)
  • BroadcastReceiver 就是应用程序间的全局大喇叭,通信的一个手段, 系统自己在很多时候都会发送广播,比如电量低或者充电已满、系统启动完、插入耳机等, 发生这些事件,系统都会发送广播,即系统广播,每个 APP 都会收到,如果想让应用在接收到这些广播的时候做一些操作,比如:系统开机后,偷偷后台跑服务啥的,这个时候只需要为应用注册一个用于监视开机的 BroadcastReceiver 即可。
  • 同时自己也可以发送广播,比如:接到服务端推送信息,用户在别处登录,然后应该强制用户下线回到登陆界面,或者提示在别处登录等

广播类型

注册广播的两种方式

  • 系统在某些时刻会发送相应的系统广播,自己的 APP 接收系统广播之前,需要注册广播接收器,注册的方法分为以下两种:动态与静态!

  • 不建议在广播中进行耗时操作,广播更多的时候扮演的是一个打开其它组件的角色,比如启动 Service,Notification 提示, 启动 Activity等

操作举例

动态注册广播

  • 环境:minSdkVersion 17、targetSdkVersion 28,现在演示动态注册广播,以监听手机网络状态为例进行说明,效果如下,当手机网络发送变化时,给出提示。

  • 布局文件 activity_main.xml 内容如下,就是生成的 helloWorld 项目默认的代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
  • 自定义 广播接收者 MyBroadcastReceiver 继承 android.content.BroadcastReceiver
package com.lct.www.yuan.broadcastReceiver;

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

/**
 * 自定义 广播接收者
 * 继承 android.content.BroadcastReceiver
 */
public class MyBroadcastReceiver extends BroadcastReceiver {
    /**
     * 接收广播消息后都会进入 onReceive 方法,然后要做的就是对相应的消息做出相应的处理
     *
     * @param context
     * @param intent
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        /**
         * android.net.ConnectivityManager 专门用于处理系统网络的管理器
         */
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        /**
         * 获取活动网络信息,此时需要在 AndroidManifest.xml 添加获取网络状态的权限:
         * <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
         */
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        /**判断是否有网络连接*/
        if (networkInfo != null && networkInfo.isConnectedOrConnecting()) {
            /**
             * TYPE_WIFI = 1:表示 WIFI
             * TYPE_MOBILE = 0:表示手机流量
             * -1:表示未知的
             * 2:An MMS-specific Mobile data connection
             * ...
             * TYPE_BLUETOOTH = 7:表示蓝牙
             */
            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                Toast.makeText(context, "无线网络已连接", Toast.LENGTH_SHORT).show();
            } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                Toast.makeText(context, "流量网络已连接", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show();
        }
    }
}
  • 主活动 MainActivity.java 内容如下:
package com.lct.www.yuan;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;

import com.lct.www.yuan.broadcastReceiver.MyBroadcastReceiver;

public class MainActivity extends AppCompatActivity {
    private BroadcastReceiver myReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i("Wmx logs::", "活动创建...");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**
         * 动态注册广播------用于接收系统网络变化状态广播信息
         */
        IntentFilter itFilter = new IntentFilter();
        itFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        myReceiver = new MyBroadcastReceiver();
        this.registerReceiver(myReceiver, itFilter);
    }

    /**
     * 当活动被销毁时
     */
    @Override
    protected void onDestroy() {
        Log.i("Wmx logs::", "活动销毁...");
        super.onDestroy();
        /**注销 unregisterReceiver(),否则可能引起内存泄露。*/
        unregisterReceiver(myReceiver);
    }
}
  • 全局配置文件 AndroidManifest.xml 内容如下,动态注册广播时可以不用在下面注册 BroadcastReceiver:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lct.www.yuan">

    <!--添加获取网络状态的权限-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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>
    </application>
</manifest>

静态注册广播

  • 静态注册广播同样需要继承 android.content.BroadcastReceiver,但之后不是在 Java 代码进行注册,而是在全局配置文件 AndroidManifest.xml 中进行配置。
  • 这里以接收开机广播为例进行说明,可以参考《Android 程序随开机自动运行

常用系统事件

  • 有许多系统产生的事件被定义为类 Intent 中的静态常量值。下面的表格列举了重要的系统事件。

猜你喜欢

转载自blog.csdn.net/wangmx1993328/article/details/82893148