什么是android中的BroadcastReceiver广播

在 Android 系统中,广播(Broadcast)是在组件之间传播数据的一种机制,这些组件可以位于不同的进程中,起到进程间通信的作用

BroadcastReceiver 是对发送出来的 Broadcast 进行过滤、接受和响应的组件。首先将要发送的消息和用于过滤的信息(Action,Category)装入一个 Intent 对象,然后通过调用 Context.sendBroadcast()sendOrderBroadcast() 方法把 Intent 对象以广播形式发送出去。 广播发送出去后,所以已注册的 BroadcastReceiver 会检查注册时的 IntentFilter 是否与发送的 Intent 相匹配,若匹配则会调用 BroadcastReceiver 的 onReceiver() 方法

所以当我们定义一个 BroadcastReceiver 的时候,都需要实现 onReceiver() 方法。BroadcastReceiver 的生命周期很短,在执行 onReceiver() 方法时才有效,一旦执行完毕,该Receiver 的生命周期就结束了

广播类型

Android中的广播分为两种类型,标准广播有序广播

  • 标准广播
    标准广播是一种完全异步执行的广播,在广播发出后所有的广播接收器会在同一时间接收到这条广播,之间没有先后顺序,效率比较高,且无法被截断
  • 有序广播
    有序广播是一种同步执行的广播,在广播发出后同一时刻只有一个广播接收器能够接收到, 优先级高的广播接收器会优先接收,当优先级高的广播接收器的 onReceiver() 方法运行结束后,广播才会继续传递,且前面的广播接收器可以选择调用 abortBroadcast()方法截断广播,这样后面的广播接收器就无法接收到这条广播了
一般广播 有序广播
多人接收时是否有序 无序,都会同时执行 有序,依据优先级和注册先后顺序依次执行
是否可以中断 不可以 可以,调用了abortBroadcas()方法中断,后面的接收器就接收不了此广播

如何发送广播

发送标准广播

发送标准广播调用的是 sendBroadcast(Intent) 方法

1
2
3
4
5
6
7
8
9
10
11
btnNormal.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//指定action 就是要发送的广播频道
Intent intent=new Intent("app.com.cn");
//在发送广播的时候,向广播接收者发送数据
intent.putExtra("name","大数据.JAVA.Android");
//下面这句代码执行广播的发送
sendBroadcast(intent);
}
});

发送有序广播

发送有序广播调用的是 sendOrderedBroadcast(Intent , String)方法,String 参数值在自定义权限时使用

1
2
3
4
5
6
7
8
btnOrder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("app.com.cn");
//发送有序广播
sendOrderedBroadcast(intent,null);
}
});

如何编写一个广播接收器

  1. 写一个类继承于BroadCastReceiver 重写 onReceive()方法

  2. 要注册广播 (静态注册、动态注册)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class MyBroadCastReceiver1 extends BroadcastReceiver {

    public MyBroadCastReceiver1(){
    Log.d("MyBroadCastReceiver1","MyBroadCastReceiver1构造方法被执行");
    }

    //这个方法是广播接收器接收到某个广播之后的回调方法
    @Override
    public void onReceive(Context context, Intent intent) {
    String name=intent.getStringExtra("name");
    Log.d("onReceive","onReceive()被执行:"+name);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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);
    }
    }

广播接收器的注册方式

凡是要接收广播的接收者,必须要进行注册: BroadCastReceiver (广播接收器),广播在注册方式上可以分为动态注册静态注册两种方式。静态注册即在清单文件中为 BroadcastReceiver 进行注册,使用< receiver >标签声明,并在标签内用 < intent-filter > 标签设置过滤器。这种形式的 BroadcastReceiver 的生命周期伴随着整个应用,如果这种方式处理的是系统广播,那么不管应用是否在运行,该广播接收器都能接收到该广播

动态注册:指的是在程序代码中进行广播注册的过程

静态注册:在AndroidManifest.xml文件进行注册,注册类

静态注册 动态注册
注册方式 配置文件(Androidmanifest.xml) java代码执行
注册时间 应用安装成功/手机开机完成 执行registerReceiver(reveiver,intent)注册时创建对象
生命结束的时间(解注册) 应用卸载(对象执行完onReceiver之后就回收) 执行unregisterReceiver(receiver),注意activity退出以后必须解注册,解注册后对象被回收
应用情景 需要监听的时间为整个应用分的生命周期时间 只服务于某个Activity或者Service

静态注册

在清单文件中注册 BroadcastReceiver

在清单文件中声明的 BroadcastReceiver ,必须包含值为 NORMAL_ACTION 字符串的 action 属性,该广播接收器才能收到以下代码中发出的广播

1
2
3
4
5
<receiver android:name=".NormalReceiver">
<intent-filter>
<action android:name="app.com.cn" />
</intent-filter>
</receiver>

注册广播优先级的配置:

在清单文件中对三个 Receiver 进行注册,指定相同的 action 属性值,Receiver 之间的优先级使用 priority 属性来判定,数值越大,优先级越高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   <receiver android:name=".MyBroadCastReceiver1">
<intent-filter>
<action android:name="app.com.cn"></action>
</intent-filter>
</receiver>

<receiver android:name=".MyBroadCastReceiver3" >
<intent-filter android:priority="2000000">
<action android:name="app.com.cn" ></action>
</intent-filter>
</receiver>

<receiver android:name=".MyBroadCastReceiver4" >
<intent-filter android:priority="2147483647">
<action android:name="app.com.cn" ></action>
</intent-filter>
</receiver>

动态注册

动态注册 BroadcastReceiver 是在代码中定义并设置好一个 IntentFilter 对象,然后在需要注册的地方调用 Context.registerReceiver() 方法,调用 Context.unregisterReceiver() 方法取消注册,此时就不需要在清单文件中注册 Receiver 了

这里采用在 Service 中注册广播接收器的形式,分别在注册广播接收器取消注册广播接受器接收到广播时输出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
25
26
27
MyBroadCastReceiver2 myBroadCastReceiver2;
//动态注册广播接收器
public void reg(View view){
if(myBroadCastReceiver2==null){
//创建要注册的广播接收器
myBroadCastReceiver2=new MyBroadCastReceiver2();
//创建意图过滤器 指定要接收的频道
IntentFilter intentFilter=new IntentFilter("app.com.cn");
//registerReceiver(要注册的广播接收器,意图过滤器);
registerReceiver(myBroadCastReceiver2,intentFilter);
//弹框提示
Toast.makeText(this,"给myBroadCastReceiver2动态注册",Toast.LENGTH_SHORT).show();

}else{
Toast.makeText(this,"myBroadCastReceiver2已经被注册过了",Toast.LENGTH_SHORT).show();
}

}

//解注册广播接收器
public void unReg(){
if(myBroadCastReceiver2!=null){
//解除刚才注册的接收器
unregisterReceiver(myBroadCastReceiver2);
myBroadCastReceiver2=null;
}
}

相关API

Context

SendBroadCast(Intent intent);发送一般广播

SendOrderedBroadCast(Intent intent); 发送有序广播

registerReceiver(receiver,intentFilter);注册广播接收器

UnRegisterReceiver(receiver); 解注册广播接收器

Android常见的系统广播

Android 内置了很多系统级别的广播,我们可以在应用程序里面通过监听这些广播来得到各种系统的状态信息。

广播 Intent
开机广播。这个动作被广播一次(只有一次) Intent.ACTION_BOOT_COMPLETED
重启设备时的广播 Intent.ACTION_REBOOT;
屏幕被关闭之后的广播 Intent.ACTION_SCREEN_OFF;
屏幕被打开之后的广播 Intent.ACTION_SCREEN_ON;
插上外部电源时发出的广播 Intent.ACTION_POWER_CONNECTED;
已断开外部电源连接时发出的广播 Intent.ACTION_POWER_DISCONNECTED;
表示电池电量低 Intent.ACTION_BATTERY_LOW;
表示电池电量充足,即从电池电量低变化到饱满时会发出广播 Intent.ACTION_BATTERY_OKAY;
充电状态,只能通过Context.registerReceiver()注册 Intent.ACTION_BATTERY_CHANGED;
关闭或打开飞行模式时的广播 Intent.ACTION_AIRPLANE_MODE_CHANGED;
设备墙纸已改变时发出的广播 Intent.ACTION_WALLPAPER_CHANGED;
设备日期发生改变时会发出此广播 Intent.ACTION_DATE_CHANGED
按下照相时的拍照按键(硬件按键)时发出的广播 Intent.ACTION_CAMERA_BUTTON;
当屏幕超时进行锁屏时,当用户按下电源按钮,长按或短按(不管有没跳出话框) Intent.ACTION_CLOSE_SYSTEM_DIALOGS;
设备当前设置被改变时发出的广播(包括的改变:界面语言,设备方向,等,请参考Configuration.java) Intent.ACTION_CONFIGURATION_CHANGED;
设备内存不足时发出的广播,此广播只能由系统使用,其它APP不可用 Intent.ACTION_DEVICE_STORAGE_LOW;
设备内存从不足到充足时发出的广播,此广播只能由系统使用,其它APP不可用 Intent.ACTION_DEVICE_STORAGE_OK;
关闭系统时发出的广播 Intent.ACTION_SHUTDOWN;
时区发生改变时发出的广播 Intent.ACTION_TIMEZONE_CHANGED;
时间被设置时发出的广播 Intent.ACTION_TIME_CHANGED;
移动APP完成之后,发出的广播(移动是指:APP2SD) Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE;
正在移动APP时,发出的广播(移动是指:APP2SD) Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
Gtalk已建立连接时发出的广播 Intent.ACTION_GTALK_SERVICE_CONNECTED;
Gtalk已断开连接时发出的广播 Intent.ACTION_GTALK_SERVICE_DISCONNECTED;
在耳机口上插入耳机时发出的广播 Intent.ACTION_HEADSET_PLUG;
改变输入法时发出的广播 Intent.ACTION_INPUT_METHOD_CHANGED;
设备当前区域设置已更改时发出的广播 Intent.ACTION_LOCALE_CHANGED;
广播:当前时间改变,每分钟都发送,只能通过Context.registerReceiver()方法来注册 Intent.ACTION_TIME_TICK;
一个用户ID已经从系统中移除发出的广播 Intent.ACTION_UID_REMOVED;
设备已进入USB大容量储存状态时发出的广播 Intent.ACTION_UMS_CONNECTED;
设备已从USB大容量储存状态转为正常状态时发出的广播 Intent.ACTION_UMS_DISCONNECTED;
表示用户和包管理所承认的低内存状态通知应该开始。 Intent.ACTION_MANAGE_PACKAGE_STORAGE;
未正确移除SD卡(正确移除SD卡的方法:设置–SD卡和设备内存–卸载SD卡),但已把SD卡取出来时发出的广播 ,扩展介质(扩展卡)已经从 SD 卡插槽拔出,但是挂载点 (mount point) 还没解除 (unmount) Intent.ACTION_MEDIA_BAD_REMOVAL;
插入SD卡并且已正确安装(识别)时发出的广播, 扩展介质被插入,而且已经被挂载。 Intent.ACTION_MEDIA_MOUNTED;
按下”Media Button” 按键时发出的广播,假如有”Media Button” 按键的话(硬件按键) Intent.ACTION_MEDIA_BUTTON;
插入外部储存装置,比如SD卡时,系统会检验SD卡,此时发出的广播? Intent.ACTION_MEDIA_CHECKING;
已拔掉外部大容量储存设备发出的广播(比如SD卡,或移动硬盘),不管有没有正确卸载都会发出此广播, 用户想要移除扩展介质(拔掉扩展卡)。 Intent.ACTION_MEDIA_EJECT;
拓展介质存在,但使用不兼容FS(或为空)的路径安装点检查介质包含在Intent.mData领域。 Intent.ACTION_MEDIA_NOFS;
外部储存设备已被移除,不管有没正确卸载,都会发出此广播, 扩展介质被移除。 Intent.ACTION_MEDIA_REMOVED;
广播:已经扫描完介质的一个目录 Intent.ACTION_MEDIA_SCANNER_FINISHED;
请求媒体扫描仪扫描文件并将其添加到媒体数据库。 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE;
广播:开始扫描介质的一个目录 Intent.ACTION_MEDIA_SCANNER_STARTED;
广播:扩展介质存在,但是还没有被挂载 (mount) Intent.ACTION_MEDIA_UNMOUNTED
广播:扩展介质的挂载被解除 (unmount),因为它已经作为 USB 大容量存储被共享。 Intent.ACTION_MEDIA_SHARED;
成功的安装APK之后,设备上新安装了一个应用程序包。 Intent.ACTION_PACKAGE_ADDED;
一个已存在的应用程序包已经改变,包括包名 Intent.ACTION_PACKAGE_CHANGED;
清除一个应用程序的数据时发出的广播(在设置--应用管理--选中某个应用,之后点清除数据时) Intent.ACTION_PACKAGE_DATA_CLEARED;
触发一个下载并且完成安装时发出的广播,比如在电子市场里下载应用 Intent.ACTION_PACKAGE_INSTALL;
成功的删除某个APK之后发出的广播, 一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播) Intent.ACTION_PACKAGE_REMOVED;
替换一个现有的安装包时发出的广播(不管现在安装的APP比之前的新还是旧,都会发出此广播) Intent.ACTION_PACKAGE_REPLACED;
用户重新开始一个包,包的所有进程将被杀死,所有与其联系的运行时间状态应该被移除,包括包名(重新开始包程序不能接收到这个广播) Intent.ACTION_PACKAGE_RESTARTED;

评论