Android开发-系统广播
一、什么是系统广播?
- 系统广播:由 Android 系统在特定事件发生时自动发送的
Intent
消息。 - 接收者:通过
BroadcastReceiver
组件监听并处理这些广播。 - 事件类型:涵盖设备生命周期、网络、电池、用户交互等多个方面。
⚠️ 重要提示:大多数系统广播是隐式广播(Implicit Broadcast),即不指定特定目标应用。从 Android 8.0 起,此类广播的静态注册受到严格限制。
二、常见系统广播清单
以下是开发者最常使用的系统广播及其说明:
广播 Action | 描述 | 权限要求 | 静态注册(Android 8.0+) |
---|---|---|---|
android.intent.action.BOOT_COMPLETED | 设备启动完成 | RECEIVE_BOOT_COMPLETED | ✅ 允许 |
android.intent.action.BATTERY_LOW | 电池电量低 | 无 | ❌ 仅动态注册 |
android.intent.action.BATTERY_OKAY | 电池电量恢复正常 | 无 | ❌ 仅动态注册 |
android.intent.action.ACTION_POWER_CONNECTED | 充电器连接 | 无 | ❌ 仅动态注册 |
android.intent.action.ACTION_POWER_DISCONNECTED | 充电器断开 | 无 | ❌ 仅动态注册 |
android.net.conn.CONNECTIVITY_CHANGE | 网络连接状态变化 | ACCESS_NETWORK_STATE | ❌ 仅动态注册 |
android.intent.action.TIMEZONE_CHANGED | 时区变更 | 无 | ✅ 允许 |
android.intent.action.TIME_SET | 系统时间被修改 | 无 | ❌ 仅动态注册 |
android.intent.action.DATE_CHANGED | 日期变更 | 无 | ❌ 仅动态注册 |
android.intent.action.PACKAGE_ADDED | 应用安装 | PACKAGE_USAGE_STATS (Android 12+ 需特殊权限) | ❌ 仅动态注册 |
android.intent.action.PACKAGE_REMOVED | 应用卸载 | PACKAGE_USAGE_STATS (Android 12+ 需特殊权限) | ❌ 仅动态注册 |
android.intent.action.LOCALE_CHANGED | 系统语言变更 | 无 | ✅ 允许 |
android.intent.action.SCREEN_ON | 屏幕点亮 | 无 | ❌ 仅动态注册 |
android.intent.action.SCREEN_OFF | 屏幕关闭 | 无 | ❌ 仅动态注册 |
android.intent.action.USER_PRESENT | 用户解锁设备 | 无 | ❌ 仅动态注册 |
🔍 说明:✅ 表示可在
AndroidManifest.xml
中静态注册;❌ 表示只能在代码中动态注册。
三、如何接收系统广播?
方式 1:静态注册(适用于允许的广播)
在 AndroidManifest.xml
中声明 BroadcastReceiver
和 intent-filter
。
<receiver android:name=".BootCompletedReceiver"android:exported="true"><intent-filter android:priority="1000"><!-- 开机完成 --><action android:name="android.intent.action.BOOT_COMPLETED" /><!-- 时区变更 --><action android:name="android.intent.action.TIMEZONE_CHANGED" /><!-- 语言变更 --><action android:name="android.intent.action.LOCALE_CHANGED" /></intent-filter>
</receiver>
🔐 添加必要权限
<!-- 接收开机广播 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><!-- 监听网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
✅ 适用场景:需要在应用未启动时也能响应的事件(如开机后自动启动服务)。
方式 2:动态注册(推荐用于大多数系统广播)
在 Activity
、Service
或 Application
中注册,生命周期可控。
public class NetworkChangeReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {boolean isConnected = isNetworkConnected(context);Log.d("Network", "网络状态:" + (isConnected ? "已连接" : "已断开"));// 执行网络相关逻辑}}private boolean isNetworkConnected(Context context) {ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo activeNetwork = cm.getActiveNetworkInfo();return activeNetwork != null && activeNetwork.isConnected();}
}
在 Activity 中注册
public class MainActivity extends AppCompatActivity {private NetworkChangeReceiver receiver;private IntentFilter filter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);receiver = new NetworkChangeReceiver();registerReceiver(receiver, filter);}@Overrideprotected void onDestroy() {super.onDestroy();// 必须反注册!if (receiver != null) {unregisterReceiver(receiver);}}
}
✅ 优点:灵活、安全、符合现代 Android 规范。
❌ 缺点:应用进程被杀后无法接收。
四、Android 8.0+ 的广播限制详解
1. 为什么限制?
- 后台滥用:部分应用滥用广播启动后台服务,消耗电量。
- 性能影响:大量广播接收者同时唤醒,影响系统流畅度。
- 用户体验:非必要的后台活动导致设备发热、耗电快。
2. 主要限制内容
- 禁止在清单中静态注册隐式广播(除少数例外)。
- 动态注册不受限,但需注意组件生命周期。
- 前台服务:如需在后台执行任务,应使用
startForegroundService()
。
3. 适配策略
- 将静态注册改为动态注册,并在
onStart()
/onStop()
中管理。 - 使用
JobScheduler
或WorkManager
替代长时间运行的广播任务。 - 利用
PendingIntent
+AlarmManager
实现定时唤醒。
五、高版本 Android(Android 12+)的特殊变化
1. PACKAGE_ADDED
/ PACKAGE_REMOVED
广播
- Android 12+:应用默认无法接收其他应用的安装/卸载广播。
- 如需此功能,必须在
AndroidManifest.xml
中声明:<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
2. ACTION_MY_PACKAGE_REPLACED
- 替代方案:如果只想知道自己应用被更新,可监听:
Intent.ACTION_MY_PACKAGE_REPLACED
六、最佳实践与替代方案
1. 最佳实践
- ✅ 优先使用动态注册,避免滥用静态注册。
- ✅ 及时反注册,防止内存泄漏。
- ✅ 避免在
onReceive()
中执行耗时操作,应启动Service
或使用WorkManager
。 - ✅ 使用
requireContext()
获取上下文。 - ✅ 为接收者添加
android:exported="true"
(如需跨应用)或false
(仅应用内)。
2. 现代替代方案
场景 | 推荐方案 |
---|---|
网络状态监听 | ConnectivityManager.NetworkCallback (更精确) |
定时任务 | WorkManager + Constraints |
应用前后台切换 | ActivityLifecycleCallbacks 或 ProcessLifecycleOwner |
数据变更通知 | LiveData 、Flow 、Room 数据库观察 |
七、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!