广播

学习

   阅读量:  

广播机制简介

Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会收到自己所关心的广播内容,这些广播可能是来自于系统的,也可能是来自于其他应用程序的。

  • 标准广播(normal broadcasts)是一种完全异步执行的广播,在广播发出之后,所有的 BroadcastReceiver几乎会在同一时刻收到这条广播消息,因此它们之间没有任何先后顺 序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。
  • 有序广播(ordered broadcasts)则是一种同步执行的广播,在广播发出之后,同一时刻 只会有一个BroadcastReceiver能够收到这条广播消息,当这个BroadcastReceiver中的 逻辑执行完毕后,广播才会继续传递。所以此时的BroadcastReceiver是有先后顺序的, 优先级高的BroadcastReceiver就可以先收到广播消息,并且前面的BroadcastReceiver 还可以截断正在传递的广播。
  • 隐式广播指的 是那些没有具体指定发送给哪个应用程序的广播,大多数系统广播属于隐式广播,但是少数特 殊的系统广播目前仍然允许使用静态注册的方式来接收。

接收系统广播

动态注册

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
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 has changed", Toast.LENGTH_SHORT).show()        		 }	 
    } 
}

完整的广播列表<Android SDK>/platforms/<任意android api版本>/data/broadcast_actions.txt

静态注册

静态注册是常驻型 ,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。 静态注册多用于接收显式广播,只有少量隐式系统广播可通过权限申请进行接收。 单独文件广播注册New→Other→Broadcast Receiver

1
2
3
4
class BootCompleteReceiver : BroadcastReceiver() { 
    override fun onReceive(context: Context, intent: Intent) { 
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show()     } 
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application>
	<receiver 
			  android:name=".BootCompleteReceiver" 
			  android:enabled="true" 
			  android:exported="true"> 
		  <intent-filter> 
			<action android:name="android.intent.action.BOOT_COMPLETED" />            			  </intent-filter> 
	 </receiver>
</application>

发射自定义广播

1
2
3
4
5
val intent =
Intent("top.xherror.firstactivity.MY_BROADCAST")
intent.setPackage(packageName)
//sendBroadcast(intent)
sendOrderedBroadcast(intent,null)

高优先级接收

1
2
3
4
5
6
7
8
<receiver
	android:name=".broadreceiver.MyReceiver"
	android:enabled="true"
	android:exported="true">
	<intent-filter android:priority="100" >
		<action android:name="top.xherror.firstactivity.MY_BROADCAST" />
	</intent-filter>
</receiver>

实现强制下线

在第一行代码中写到:

创建的是一个静态注册的BroadcastReceiver,是没有办法在onReceive()方法里弹出对话框这样的UI控件的

因此书上采用动态注册,通过各种搜索找到了静态注册的方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class SignInReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val builder= AlertDialog.Builder(context)
        builder.run {
            setTitle("Warning")
            setMessage("You are forced to be offline.Please try to sign in again")
            setCancelable(false)
            setPositiveButton("OK"){dialog,which->
                BaseActivity.finishAll()
                val intent =Intent(context,SignInActivity::class.java)
				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                context.startActivity(intent)
            }
        }
        val alterDialog = builder.create()
        //添加对话框类型:保证在广播中正常弹出
        alterDialog.window?.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY)
        alterDialog.show()
    }
}

Manifest中申请权限:

1
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

申请权限后,当然需要用户授权,路径Apps->Advanced->Display over other Apps

73c9b0bb1dc9ab907c12c661822c5b54.png

https://blog.csdn.net/weixin_43884551/article/details/107569418

https://blog.csdn.net/u012504392/article/details/53011172

Licensed under CC BY-NC-SA 4.0
最后更新于 Dec 19, 2022 13:55 +0800