Android中的每个应用程序都可以对自己感兴趣的广播进行注册。Android提供了一套完整的API,允许运行程序自有的发送和接收广播。
Android中的广播可以分为两种类型:标准广播和有序广播。
- 标准广播是一种异步执行的广播,在广播发出后,所有的BroadcastReceiver几乎会同时收到这条广播,没有顺序可言。这种广播比较高效且无法被截断。
- 有序广播是一种同步执行的广播,广播发出后,同一时间只会有一个BroadcastReceiver能接收到,当这个BroadcastReceiver的逻辑执行完毕后,广播才能继续传递,所以是有顺序的,优先级高的BroadcastReceiver优先接收,还可以截断正在传递的广播。
接收系统广播就需要我们了解使用BroadcastReceiver,接下来学习一下具体用法。
动态注册监听时间变化
注册BroadcastReceiver的方式一般有两种:在代码中注册和在AndroidManifest.xml注册。前者也被称为动态注册,后者也被称为静态注册。
那么创建BroadcastReceiver只需新建一个类,让它继承自BroadcastReceiver,并重写父类的onReceive()方法。这样广播来临时onReceive()方法就会执行,具体的逻辑就可以在这个方法中处理。
现在我们通过动态注册的方式编写一个能够监听时间变化的程序。新建一个BroadcastTest项目,修改MainActivity的代码如下:
class MainActivity : AppCompatActivity() {
lateinit var timeChangeReceiver: TimeChangeReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intentFilter= IntentFilter()
intentFilter.addAction("android.intent.action.TIME_TICK")
timeChangeReceiver=TimeChangeReceiver()
registerReceiver(timeChangeReceiver,intentFilter)
}
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(timeChangeReceiver)
}
inner class TimeChangeReceiver : BroadcastReceiver(){
override fun onReceive(context: Context, intent: Intent){
Toast.makeText(context,"Time is changed",Toast.LENGTH_SHORT).show()
}
}
}
我们新建了一个继承自BroadcastReceiver的内部类,并重写父类的onReceive()方法。然后在onCreate()方法创建了一个IntentFilter的实例,并给他添加了一个Action的值。这个Action的值是系统发出的广播的值。接下来创建一个TimeChangeReceiver的实例,然后调用registerReceiver()方法进行注册,将两个实例都传进去,这样TimeChangeReceiver()方法就会收到所有值为上述action的广播,也就实现了监听系统时间变化的功能。
动态注册的BroadcastReceiver记得取消,这里我们在onDestroy()方法中通过调unregisterReceiver()方法注册。
运行程序后,最多等待一分钟我们就能收到这条广播了。
静态注册实现开机自动
动态注册的BroadcastReceiver可以自由注册或注销,在灵活性方面有很大优势,但它必须在程序启动后才能接收广播,因为注册逻辑是在onCreate()方法中的。
那么如果想在未启动时就接收广播就需要静态注册。那些没有具体指定发送给哪个程序的广播称为隐式广播,这种广播大都不允许使用静态注册的方式来接收了,但是还有少数特殊的广播仍然允许。这里我们用开机广播来举例。
这里准备实现一个开机启动的功能。使用静态注册的方法接收开机广播,然后在onReceive()方法里执行相应的逻辑就可以了。
这次我们通过AndroidStudio的快捷方式来创建BroadcastReceiver。我们将这里的类命名为BootCompletReceiver,Export属性表示是否允许这BroadcastReceiver接收本程序以外的广播,Enable属性表示是否启用BroadcastReceiver。
修改这个类中的代码:
class BootCompleteReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Toast.makeText(context,"Boot complete",Toast.LENGTH_LONG).show()
}
}
此外,静态的