BroadcastReceiver
发送一条广播,可以被不同的广播接收者所接收,广播接收者收到广播后再进行逻辑判断。
标准广播
通过 new BroadcastReceiver()
创建广播
通过 registerReceiver()
注册广播
通过 sendBroadcast()
发送广播
通过 unregisterReceiver()
注销广播
@Override
protected void onStart() {
super.onStart();
receiver = new BroadcastReceiver() {
@Override
public 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);
}
发送标准广播
@Override
public void onClick(View view) {
Intent intent = new Intent(BroadStandardActivity.BROAD_ACTION_COME);
sendBroadcast(intent);
}
有序广播
- 一个广播存在多个接收器,这些接收器需要排队收听广播,这意味着该广播是条有序广播。
- 先收到广播的接收器A,既可让其他接收器继续收听广播,也可中断广播不让其他接收器收听。
通过 sendOrderedBroadcast()
发送广播
通过 setPriority()
设置优先级,数字越大,优先级越高
@Override
protected void onStart() {
super.onStart();
/*
* 多个接收器处理有序广播的规则:
* 1、优先级越大的接收器,越早收到有序广播
* 2、优先级相同的时候,越早注册的接收器越早收到有序广播
* */
/*
* 创建接收器A
* */
receiverA = new BroadcastReceiver() {
@Override
public 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() {
@Override
public 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;
发送有序广播
@Override
public 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() {
@Override
public 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_MUTABLE
PendingIntent 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);
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction().equals(ALARM_ACTION)) {
Log.d("AAAA", "收到广播了");
// setRepeating 有问题,在接收到广播后又调用一次
sendAlarm();
}
}