两种广播机制:

  1. 标准广播:完全异步执行的广播,几乎所有接受者都会同时受到这个广播消息。这种广播效率高,这也意味着它不能被截断
  2. 有序广播:同步执行的广播,根据接收者优先级顺序依次发送。而且中途可以被截断。A–>B–>C;B可以在中途截断广播的传输。

接受系统广播

android内置了很多系统级别的广播,比如手机开机,电量变化。这些都可以接收。

  1. 动态接收
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    class MainActivity : AppCompatActivity() {
    //声明一个时间改变接收器,它继承自BroadcastReceiver
    lateinit var timeChangeReceiver: TimeChangeReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //声明一个intent过滤器,他和androidManifest中的配置项一样,可以限定接收那些action,catogory。
    val intentFilter = IntentFilter()
    //接收时间改变动作
    intentFilter.addAction("android.intent.action.TIME_TICK")
    timeChangeReceiver = TimeChangeReceiver()
    //将该过滤器接收到的广播消息交给时间改变接收器
    registerReceiver(timeChangeReceiver,intentFilter)
    }

    override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(timeChangeReceiver)
    }

    //它通过重写onReceive方法去回调的执行方法
    inner class TimeChangeReceiver:BroadcastReceiver(){
    override fun onReceive(context: Context, intent:Intent) {

    Toast.makeText(context,"Time has changed",Toast.LENGTH_SHORT).show()
    }

    }
    }

2.静态接收
静态接收的步骤也简单:

  1. 声明一个BroadcastReceiver类,并重写他的onReceive方法
  2. 在AndroidManifest中注册使用它:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <activity
    android:name=".MainActivity"
    android:exported="true">
    <intent-filter>
    <action android:name="android.intent.action.MAIN"/>

    <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    </activity>
    这里表示它接收一个开启信号。

    Android为了保护用户的隐私,有着严格的规定,对于某些比较敏感的操作,必须声明权限。不然程序直接奔溃无法启动。例如:

    1
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    就必须声明了接收开机信号,才能在receiver中使用。

注意,不要再broadcast的onReceive中添加过多的逻辑,或者耗时操作。因为onReceive是不允许开启线程的。如果它运行了过长时间,程序就会报错。

发送广播

标准广播

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.apply {
button.setOnClickListener {
val intent = Intent("top.zfxt.My_BROADCAST")
//默认情况下我们发出的都是隐式广播,而Android8.0后,静态注册的接收器无法接收隐式广播
//因此我们需要显式的声明问要发给那个应用程序的,将他变为显示广播
intent.setPackage(packageName)
sendBroadcast(intent)
}
}
}

}

这里我们用Intent来发送广播,发送一个我们自定义的广播:top.zfxt.My_BROADCAST。然后定义receive会接收该广播

1
2
3
4
5
6
7
8
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="top.zfxt.My_BROADCAST"/>
</intent-filter>
</receiver>

有序广播

  1. 将sendBroadcast换成sendOrderBroadcast
    1
    2
    3
    //                sendBroadcast(intent)
    //发送有序广播,第一个参数就是发送的intent,第二个参数是与权限相关的字符串。
    sendOrderedBroadcast(intent,null)
  2. 发送有序广播的话,需要定义接收器的优先级,顺序。通过priority来定义。如:
    <intent-filter android:priority="100">
    数字越大,优先级越高。
  3. 有序广播是可以阻断的,所以可以再onReceive中使用abortBroadcast(),这个方法将会阻断广播的传播。