BroadcastReceiver
发送一条广播,可以被不同的广播接收者所接收,广播接收者收到广播后再进行逻辑判断。
标准广播
通过 new BroadcastReceiver()
创建广播
通过 registerReceiver()
注册广播
通过 sendBroadcast()
发送广播
通过 unregisterReceiver()
注销广播
@Overrideprotected void onStart() {super.onStart();receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null && intent.getAction().equals(BroadStandardActivity.BROAD_ACTION_COME)) {btn_send.setText("来了");}}};// 创建一个意图过滤器,只处理 BROAD_ACTION_COME 的广播IntentFilter filter = new IntentFilter(BroadStandardActivity.BROAD_ACTION_COME);//注册接收器registerReceiver(receiver, filter);}
发送标准广播
@Overridepublic void onClick(View view) {Intent intent = new Intent(BroadStandardActivity.BROAD_ACTION_COME);sendBroadcast(intent);}
案例代码
有序广播
- 一个广播存在多个接收器,这些接收器需要排队收听广播,这意味着该广播是条有序广播。
- 先收到广播的接收器A,既可让其他接收器继续收听广播,也可中断广播不让其他接收器收听。
通过 sendOrderedBroadcast()
发送广播
通过 setPriority()
设置优先级,数字越大,优先级越高
@Overrideprotected void onStart() {super.onStart();/** 多个接收器处理有序广播的规则:* 1、优先级越大的接收器,越早收到有序广播* 2、优先级相同的时候,越早注册的接收器越早收到有序广播* *//** 创建接收器A* */receiverA = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null && intent.getAction().equals(ORDER_ACTION)) {btn_send_order.setText("来了A");}}};IntentFilter filterA = new IntentFilter(ORDER_ACTION);filterA.setPriority(8);registerReceiver(receiverA, filterA);/** 创建接收器B* */receiverB = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null && intent.getAction().equals(ORDER_ACTION)) {btn_send_order.setText("来了");abortBroadcast();// 中断广播,此时后面的接收器无法收到该广播}}};IntentFilter filterB = new IntentFilter(ORDER_ACTION);filterB.setPriority(10);registerReceiver(receiverB, filterB);}
abortBroadcast()
:中断广播,让其它广播接收者无法收到该广播
clearAbortBroadcast()
:这个方法是针对上面的abortBroadcast()方法的,用于取消截获广播。这样它的下一级广播接收者就能够收到该广播了。
getAbortBroadcast()
:判断是否调用了 abortBroadcast,如果先调用 abortBroadcast,接着再调用 getAbortBroadcast,将返回 true; 如果在调用 abortBroadcast、clearAbortBroadcast 、 getAbortBroadcast,将返回 false;
发送有序广播
@Overridepublic void onClick(View view) {Intent intent = new Intent(ORDER_ACTION);/** 发送有序广播* 第二个参数:广播接收者所需要的权限(有些广播的是需要权限的)* */sendOrderedBroadcast(intent, null);}
案例代码
系统分钟到达广播
安卓系统每到1分钟就会发送一条广播,此时我们可以接受这个广播。
通过 Intent.ACTION_TIME_TICK
进行Action过滤
IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);
网络变更广播
private void netWorkReceiver() {receiverNet = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null) {NetworkInfo networkInfo = intent.getParcelableExtra("networkInfo");String text = String.format("网络大类为%s,网络小类为%s,网络状态为%s",networkInfo.getTypeName(),networkInfo.getSubtypeName(),networkInfo.getState().toString());tv_tip.setText(text);}}};IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");registerReceiver(receiverNet, filter);}
定时管理器
Android提供了专门的定时管理器 AlarmManager,它利用系统闹钟定时发送广播,常见方法:
- set:设置一次性定时器
- setAndAllowWhileIdle:设置一次性定时器,即使设备处于空闲状态,也会保证执行定时器。
- setRepeating:设置重复定时器,但系统不保证按时发送广播。
- cancel:取消指定延迟意图的定时器。
注册接收者 AlarmReceiver
// 上下文传 getApplicationContext() ,而非 this(当前Activity),为了避免内存泄漏alarmReceiver = new AlarmReceiver(getApplicationContext());IntentFilter filter = new IntentFilter(AlarmReceiver.ALARM_ACTION);registerReceiver(alarmReceiver, filter);
发送闹钟广播
定时管理使用了PendingIntent,它与Intent之间的差异主要有下列三点:
- PendingIntent 代表延迟意图,它指向的组件不会马上激活;而Intent代表实事的意图,它指向的组件会马上激活
- PendingIntent 是一类消息的组合,不但包含目标的Intent对象, 还包含请求代码、请求方式等信息。
- PendingIntent 对象在创建之时便已知晓将要用于活动还是广播。
public void sendAlarm() {Intent intent = new Intent(ALARM_ACTION);// 创建一个用于广播的延迟意图// 针对 S+ (版本1000及更高版本)要求创建 PendingIntent 时指定 FLAG_IMMUTABLE 或 FLAG_MUTABLE// 强烈考虑使用 FLAG_IMMUTABLE,仅当某些功能依赖于 PendingIntent,是可变时才使用 FLAG_MUTABLEPendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE);// 从系统服务中获取闹钟管理器AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 允许在空闲时发送广播,Android6.0之后新增的方法alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 3000, pendingIntent);} else {// 设置一次性闹钟,延迟若干秒后,携带延迟意图发送闹钟广播(但Android6.0之后,set方法在暗屏时不保证发送广播,必须调用setAndAllowWhileIdle方法)alarmManager.set(AlarmManager.RTC_WAKEUP, 3000, pendingIntent);}}
设置重复闹钟
// 设置重复闹钟,每隔一定间隔就发送闹钟广播(但从Android4.4开始,setRepeating方法不保证按时发送广播)
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, pendingIntent);
@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null && intent.getAction().equals(ALARM_ACTION)) {Log.d("AAAA", "收到广播了");// setRepeating 有问题,在接收到广播后又调用一次sendAlarm();}}
案例代码