BroadcastReceiver #
一、BroadcastReceiver概述 #
BroadcastReceiver(广播接收器)是Android四大组件之一,用于接收和处理系统或应用发出的广播消息。广播是一种广泛使用的通信机制,可以实现跨进程、跨应用的通信。
1.1 广播的类型 #
| 类型 | 说明 |
|---|---|
| 标准广播 | 异步执行,所有接收者同时接收 |
| 有序广播 | 同步执行,按优先级顺序接收,可截断 |
| 本地广播 | 只在应用内部传递,安全性高 |
| 粘性广播 | 已废弃,发送后一直存在 |
1.2 广播的应用场景 #
- 系统事件监听(开机、网络变化、电量变化等)
- 应用间通信
- 应用内组件通信
- 定时任务触发
二、广播接收器的注册 #
2.1 静态注册 #
在AndroidManifest.xml中注册,应用未启动时也能接收广播:
xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application>
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
</manifest>
kotlin
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
Intent.ACTION_BOOT_COMPLETED -> {
Log.d("BootReceiver", "设备启动完成")
// 启动服务
context?.startService(Intent(context, MyService::class.java))
}
}
}
}
2.2 动态注册 #
在代码中注册,需要手动注销:
kotlin
class MainActivity : AppCompatActivity() {
private val networkReceiver = NetworkReceiver()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 注册广播接收器
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
registerReceiver(networkReceiver, filter)
}
override fun onDestroy() {
super.onDestroy()
// 注销广播接收器
unregisterReceiver(networkReceiver)
}
}
class NetworkReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val cm = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = cm.activeNetworkInfo
if (networkInfo?.isConnected == true) {
Log.d("NetworkReceiver", "网络已连接")
} else {
Log.d("NetworkReceiver", "网络已断开")
}
}
}
2.3 静态注册 vs 动态注册 #
| 特性 | 静态注册 | 动态注册 |
|---|---|---|
| 注册时机 | 应用安装时 | 代码执行时 |
| 生命周期 | 始终有效 | 跟随注册组件 |
| 资源消耗 | 较高 | 较低 |
| 灵活性 | 较低 | 较高 |
| Android限制 | 部分系统广播受限 | 无限制 |
三、发送广播 #
3.1 发送标准广播 #
kotlin
// 发送自定义广播
val intent = Intent("com.example.MY_ACTION")
intent.putExtra("message", "Hello, Broadcast!")
sendBroadcast(intent)
// 发送系统广播
val intent = Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED)
intent.putExtra("state", true)
sendBroadcast(intent)
3.2 发送有序广播 #
kotlin
// 发送有序广播
val intent = Intent("com.example.ORDERED_ACTION")
intent.putExtra("message", "Hello, Ordered Broadcast!")
sendOrderedBroadcast(intent, null)
接收有序广播:
kotlin
class OrderedReceiver1 : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.d("Receiver1", "收到广播")
// 获取数据
val message = getResultData()
Log.d("Receiver1", "消息: $message")
// 修改数据并传递
setResultData("Receiver1处理后的消息")
// 可以截断广播
// abortBroadcast()
}
}
class OrderedReceiver2 : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val message = getResultData()
Log.d("Receiver2", "消息: $message")
}
}
设置优先级:
xml
<receiver android:name=".OrderedReceiver1">
<intent-filter android:priority="100">
<action android:name="com.example.ORDERED_ACTION" />
</intent-filter>
</receiver>
<receiver android:name=".OrderedReceiver2">
<intent-filter android:priority="50">
<action android:name="com.example.ORDERED_ACTION" />
</intent-filter>
</receiver>
3.3 发送本地广播 #
使用LocalBroadcastManager发送只在应用内部传递的广播:
kotlin
class MainActivity : AppCompatActivity() {
private val localReceiver = LocalReceiver()
private lateinit var localBroadcastManager: LocalBroadcastManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
localBroadcastManager = LocalBroadcastManager.getInstance(this)
// 注册本地广播接收器
val filter = IntentFilter("com.example.LOCAL_ACTION")
localBroadcastManager.registerReceiver(localReceiver, filter)
// 发送本地广播
val intent = Intent("com.example.LOCAL_ACTION")
intent.putExtra("message", "本地广播消息")
localBroadcastManager.sendBroadcast(intent)
}
override fun onDestroy() {
super.onDestroy()
localBroadcastManager.unregisterReceiver(localReceiver)
}
}
class LocalReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val message = intent?.getStringExtra("message")
Log.d("LocalReceiver", "收到本地广播: $message")
}
}
四、常见系统广播 #
4.1 系统广播Action #
| Action | 说明 |
|---|---|
| Intent.ACTION_BOOT_COMPLETED | 设备启动完成 |
| Intent.ACTION_SHUTDOWN | 设备关机 |
| Intent.ACTION_BATTERY_LOW | 电量低 |
| Intent.ACTION_BATTERY_OKAY | 电量恢复 |
| Intent.ACTION_POWER_CONNECTED | 连接电源 |
| Intent.ACTION_POWER_DISCONNECTED | 断开电源 |
| Intent.ACTION_AIRPLANE_MODE_CHANGED | 飞行模式状态改变 |
| ConnectivityManager.CONNECTIVITY_ACTION | 网络连接变化 |
| Intent.ACTION_TIME_TICK | 时间变化(每分钟) |
| Intent.ACTION_DATE_CHANGED | 日期变化 |
| Intent.ACTION_SCREEN_ON | 屏幕点亮 |
| Intent.ACTION_SCREEN_OFF | 屏幕熄灭 |
4.2 开机启动服务 #
xml
<manifest>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application>
<receiver android:name=".BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
kotlin
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == Intent.ACTION_BOOT_COMPLETED) {
val serviceIntent = Intent(context, MyService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context?.startForegroundService(serviceIntent)
} else {
context?.startService(serviceIntent)
}
}
}
}
4.3 网络状态监听 #
kotlin
class NetworkReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val cm = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = cm.activeNetwork
val capabilities = cm.getNetworkCapabilities(network)
val isWifi = capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true
val isCellular = capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true
when {
isWifi -> Log.d("Network", "WiFi已连接")
isCellular -> Log.d("Network", "移动数据已连接")
else -> Log.d("Network", "网络已断开")
}
} else {
val networkInfo = cm.activeNetworkInfo
when (networkInfo?.type) {
ConnectivityManager.TYPE_WIFI -> Log.d("Network", "WiFi已连接")
ConnectivityManager.TYPE_MOBILE -> Log.d("Network", "移动数据已连接")
else -> Log.d("Network", "网络已断开")
}
}
}
}
五、广播权限 #
5.1 发送带权限的广播 #
kotlin
// 发送广播时声明权限
sendBroadcast(intent, "com.example.MY_PERMISSION")
5.2 接收带权限的广播 #
xml
<manifest>
<!-- 声明权限 -->
<permission android:name="com.example.MY_PERMISSION" />
<!-- 使用权限 -->
<uses-permission android:name="com.example.MY_PERMISSION" />
</manifest>
5.3 注册时声明权限 #
xml
<receiver
android:name=".MyReceiver"
android:permission="com.example.SENDER_PERMISSION">
<intent-filter>
<action android:name="com.example.MY_ACTION" />
</intent-filter>
</receiver>
六、Android版本限制 #
6.1 Android 8.0+ 后台执行限制 #
从Android 8.0开始,大部分隐式广播不能静态注册:
kotlin
// 不能静态注册的广播示例
// ACTION_NEW_PICTURE
// ACTION_NEW_VIDEO
// CONNECTIVITY_ACTION
// 等...
// 解决方案:使用动态注册或JobScheduler
6.2 允许静态注册的广播 #
- ACTION_BOOT_COMPLETED
- ACTION_LOCKED_BOOT_COMPLETED
- ACTION_TIMEZONE_CHANGED
- ACTION_TIME_SET
- 等…
七、最佳实践 #
7.1 使用本地广播 #
对于应用内部通信,优先使用LocalBroadcastManager:
kotlin
// 优点:
// 1. 安全性高,不会被其他应用接收
// 2. 效率高,不需要跨进程通信
// 3. 不会被恶意应用伪造
7.2 避免在onReceive中执行耗时操作 #
kotlin
class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// 错误:onReceive执行时间不能超过10秒
// 正确:启动Service处理耗时任务
val serviceIntent = Intent(context, MyService::class.java)
serviceIntent.putExtras(intent ?: return)
context?.startService(serviceIntent)
}
}
7.3 使用EventBus或LiveData替代广播 #
对于应用内部通信,可以使用更现代的方式:
kotlin
// 使用LiveData
class EventViewModel : ViewModel() {
private val _message = MutableLiveData<String>()
val message: LiveData<String> = _message
fun sendMessage(msg: String) {
_message.value = msg
}
}
// 在Activity中观察
viewModel.message.observe(this) { message ->
// 处理消息
}
八、总结 #
本章详细介绍了BroadcastReceiver:
- 广播的类型和应用场景
- 静态注册和动态注册
- 发送标准广播、有序广播、本地广播
- 常见系统广播的使用
- 广播权限管理
- Android版本限制
- 最佳实践
BroadcastReceiver是Android组件间通信的重要机制,合理使用可以提高应用的灵活性和解耦性。
最后更新:2026-03-26