BroadcastReceiver
广播(Broadcast)是在组件之间传播数据的一种机制,这些组件可以位于不同的进程中,起到进程间通信的作用
BroadcastReceiver 是对发送出来的 Broadcast 进行过滤、接受和响应的组件。首先将要发送的消息和用于过滤的信息(Action,Category)装入一个 Intent 对象,然后通过调用 context.sendBroadcast() 、 sendOrderBroadcast() 方法把 Intent 对象以广播形式发送出去。 广播发送出去后,所有已注册的 BroadcastReceiver 会检查注册时的 IntentFilter 是否与发送的 Intent 相匹配,若匹配则会调用 BroadcastReceiver 的 onReceiver() 方法
所以当我们定义一个 BroadcastReceiver 的时候,都需要实现 onReceiver() 方法。BroadcastReceiver 的生命周期很短,在执行 onReceiver() 方法时才有效,一旦执行完毕,该Receiver 的生命周期就结束了
注意
target 26 之后,无法在 AndroidManifest 显示声明大部分广播,除了一部分必要的广播,如:
- ACTION_BOOT_COMPLETED
- ACTION_TIME_SET
- ACTION_LOCALE_CHANGED
动态注册实现
动态注册 BroadcastReceiver 是在代码中定义并设置好一个 IntentFilter 对象,然后在需要注册的地方调用 Context.registerReceiver() 方法,调用 Context.unregisterReceiver() 方法取消注册,此时就不需要在清单文件中注册 receiver 了
监听电量变化
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private BatteryLevelReceiver blReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerBatteryLevelRegister();
}
private void registerBatteryLevelRegister() {
//第二步:要收听的频道:电量变化
IntentFilter intentFilter = new IntentFilter();
//第三步:设置频道
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
//第四步
blReceiver = new BatteryLevelReceiver();
//第五步:注册广播
this.registerReceiver(blReceiver, intentFilter);
}
/**
* 第一步:创建一个广播接收者,继承自BroadcastReceiver
*/
private class BatteryLevelReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "--------onReceive: " + action);
Log.d(TAG, "--------onReceive: " + "当前电量为:" + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0));
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消广播注册,否则会导致内存泄漏
if (blReceiver != null) {
this.unregisterReceiver(blReceiver);
Log.d(TAG, "--------onDestroy: "+"取消广播注册");
}
}
}
2019-09-25 19:29:47.117 2987-2987/? D/MainActivity: --------onReceive: android.intent.action.BATTERY_CHANGED
2019-09-25 19:29:47.117 2987-2987/? D/MainActivity: --------onReceive: 当前电量为:65
2019-09-25 19:29:48.468 2987-2987/com.fr.broadcastsapp D/MainActivity: --------onDestroy: 取消广播注册
静态注册实现
静态注册即在清单文件中为 BroadcastReceiver 进行注册,使用 < receiver > 标签声明,并在标签内用 < intent-filter > 标签设置过滤器。这种形式的 BroadcastReceiver 的生命周期伴随着整个应用,如果这种方式处理的是系统广播,那么不管应用是否在运行,该广播接收器都能接收到该广播
开机广播监听
public class MyReceiver extends BroadcastReceiver {
private static final String TAG = "MyReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "--------onReceive: "+action);
Log.d(TAG, "--------onReceive: "+"开机完成...");
}
}
AndroidManifest.xml中注册BroadcastReceiver
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="false">
<!--和动态注册设置action是一样的-->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
2019-09-25 19:50:40.345 4478-4478/com.fr.broadcastsapp D/MyReceiver: --------onReceive: android.intent.action.BOOT_COMPLETED
2019-09-25 19:50:40.345 4478-4478/com.fr.broadcastsapp D/MyReceiver: --------onReceive: 开机完成...
应用安装与卸载监听
public class AppStatusChangeReceiver extends BroadcastReceiver {
private static final String TAG = "AppStatusChangeReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null){
switch (action) {
case Intent.ACTION_PACKAGE_ADDED:
//应用的安装
Log.d(TAG, "--------onReceive: 应用被安装了:"+intent.getData());
break;
case Intent.ACTION_PACKAGE_REMOVED:
//应用的卸载
Log.d(TAG, "--------onReceive: 应用被卸载了:"+intent.getData());
break;
default:
break;
}
}
}
}
<receiver
android:name=".AppStatusChangeReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<!--应用卸载-->
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<!--应用安装-->
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package" />
</intent-filter>
</receiver>