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:

  1. 广播的类型和应用场景
  2. 静态注册和动态注册
  3. 发送标准广播、有序广播、本地广播
  4. 常见系统广播的使用
  5. 广播权限管理
  6. Android版本限制
  7. 最佳实践

BroadcastReceiver是Android组件间通信的重要机制,合理使用可以提高应用的灵活性和解耦性。

最后更新:2026-03-26