Android app能够发送广播也能够接收系统或者其它app发送的广播,是发送/订阅的设计模式。这些广播被发送当重要的事件发生的时候。例如,安卓系统发送广播当各类各样系统事件发生的时候,好比手机启动了或者手机开始充电了。应用也能够发送自定义广播,例如通知其它应用一些他们可能感兴趣的东西,好比一些新的内容被下载了。android
系统广播会在系统事件发生的时候被发送出来,好比当手机进入或者退出开发者选项的时候,全部订阅了系统广播的人均可以收到这个广播。设计模式
广播它自身是被包裹在了一个Intent里面,它是有一个惟一的标识的(例如android.intent.action.AIRPLANE_MODE)。这个Intent对象同时包含了一些其它的信息,在它的字段里面,飞行模式这个intent里面就包含了一个boolean的字段来表示飞行模式是开启仍是关闭的。网络
从不一样的纬度区分,可能分为不一样的类别。app
<receiver android:name=".MyBroadcastReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.INPUT_METHOD_CHANGED" /> </intent-filter> </receiver>
val br: BroadcastReceiver = MyBroadcastReceiver() val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply { addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED) } registerReceiver(br, filter)
Intent().also { intent -> intent.setAction("com.example.broadcast.MY_NOTIFICATION") intent.putExtra("data", "Notice me senpai!") sendBroadcast(intent) }
sendBroadcast(Intent("com.example.NOTIFY"), Manifest.permission.SEND_SMS)
<uses-permission android:name="android.permission.SEND_SMS"/>
private const val TAG = "MyBroadcastReceiver" class MyBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { StringBuilder().apply { append("Action: ${intent.action}\n") append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n") toString().also { log -> Log.d(TAG, log) Toast.makeText(context, log, Toast.LENGTH_LONG).show() } } } }
<receiver android:name=".MyBroadcastReceiver" android:permission="android.permission.SEND_SMS"> <intent-filter> <action android:name="android.intent.action.AIRPLANE_MODE"/> </intent-filter> </receiver>
var filter = IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED) registerReceiver(receiver, filter, Manifest.permission.SEND_SMS, null )
<uses-permission android:name="android.permission.SEND_SMS"/>
从Android 9(API level 28)开始,NETWORK_STATE_CHANGED_ACTION
广播不会携带用户的地理位置信息或者我的身份数据。 此外,当你的app运行在Android 9或者更高的手机上,系统的wifi广播也不会携带SSIDs, BSSIDs,链接信息或扫描结果。想获取以上信息,须要经过getConnectionInfo()
来代替。ide
从Android 8(API level 27)开始,系统增强了对静态广播的进一步限制,许多广播静态注册了也是收不到的,不过你能够采用动态注册的方式来接收这些广播。学习
从Android 7(API level 24)开始,系统不会再发送ACTION_NEW_PICTURE
,ACTION_NEW_VIDEO
的广播。 同时从7.0开始app想要接受CONNECTIVITY_ACTION
广播,须要经过动态注册广播的形式了,再经过静态广播注册的方式是不能够的了。ui
看图吧,画了一幅图设计
众所周知广播是会形成ANR的,形成ANR就是由于发送方将广播发送给AMS,而后AMS找有没有人注册,找到以后让它去执行,在执行开始以前AMS就开始为ANR进行耗时统计了,若是这个时候app进程已经存在,那么便把这个消息加入到消息队列中,等待调度,最后执行完成。若是app不存在,AMS会拉活咱们的进程,而后咱们的app会执行这个消息,因此若是咱们被广播拉活,咱们的启动时长也是会被统计到ANR的时间范围内的。 今年年初我花一个月的时间收录整理了一套知识体系,若是有想法深刻的系统化的去学习的,能够点击传送门,我会把我收录整理的资料都送给你们,帮助你们更快的进阶。code