android动态注册广播权限,记动态注册广播权限问题
发布日期:2021-10-31 14:06:58 浏览次数:24 分类:技术文章

本文共 6643 字,大约阅读时间需要 22 分钟。

最近在开发过程中遇到一个需求,就是跨进程的广播通信,一番尝试之后发现首先好像静态注册广播的方式行不通了,因为在Android 8.0的改动中,限制了大部分的隐式广播注册,常见的解决方案有两种:一种是通过intent.setComponent方法将意图改为显式的。另一种方法就是改为动态注册了。

ps:关于Android 8.0中关于广播的改动可以查看官方文档Android 8.0 行为变更中的后台执行限制部分。

跨进程的广播发送与接收解决了之后,我还想添加一个权限限制,让其他程序如果碰巧发送了同样Action的广播后我自己注册的接收器不会接受,其他程序注册的接收器不会收到我自己发出的同样Action的广播。但是经过一番想当然的尝试之后失败了,于是再次去翻文档,然后通过demo测试实践了一番。这里先简单小结一下=:

简单的权限限制分为两类,一类是带有权限的发送,用于限制接收器的,只有申请了相应权限的接收器才能接收到广播。另一类是带有权限的接收,用于限制发送广播的一方,在发送广播时使用sendBroadcast(Intent,String)方法发送广播。

如果想要实现A应用发送的广播只有B应用可以接收到,B应用只能接收到A应用发出的广播(注意这里虽然两句话表述好像一致,但是其实包含的情况是不同的),应该就需要在注册广播时通过permissionGroup以及protectionLevel等属性去做更近一步的限制了,具体的实现这里就没有再继续下去了,后面有时间的话可以通过文档permission对这两个属性的介绍尝试一下。

下面根据官方文档广播概况以及具体的Demo实际感受一下两种通过权限限制的广播:

带权限的发送

这种方式可以用来限制广播接收器,在发送广播的一方通过sendBroadcast(Intent,String)方法发送他广播,然后声明了相应权限的的一方中注册的广播接收器才能收到广播。使用这种方式权限需要声明在广播发送方。

Project A -- (BroadcastTest1):

package="com.example.broadcasttest1">

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:roundIcon="@mipmap/ic_launcher_round"

android:supportsRtl="true"

android:theme="@style/AppTheme">

...

class MainActivity : AppCompatActivity() {

companion object {

const val TAG = "MainActivity"

const val ACTION = "com.yu.hu.action.BUGREPPORT"

const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"

}

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

val button = findViewById(R.id.send_btn)

//添加button点击事件

button.setOnClickListener {

val intent = Intent(ACTION)

intent.putExtra("test", "test")

Log.d(TAG, "send BroadcastReceiver with permission")

//带有权限的发送 接收方必须申请相应权限才能正常接受到

sendBroadcast(intent,PERMISSION)

}

}

}

Project B -- (BroadcastTest2):

package="com.example.broadcasttest2">

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:roundIcon="@mipmap/ic_launcher_round"

android:supportsRtl="true"

android:theme="@style/AppTheme">

...

class BugReportReceiver : BroadcastReceiver() {

companion object {

const val TAG = "BugReportReceiver"

const val ACTION = "com.yu.hu.action.BUGREPPORT"

const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"

}

override fun onReceive(context: Context?, intent: Intent?) {

val value = intent?.getStringExtra("test")

Log.d(TAG, "onReceive: msg = $value")

Toast.makeText(context, "msg2 = $value", Toast.LENGTH_SHORT).show()

}

}

class MainActivity : AppCompatActivity() {

companion object {

const val TAG = "MainActivity2"

const val ACTION = "com.yu.hu.action.BUGREPPORT"

const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"

}

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

val ifl = IntentFilter()

ifl.addAction(BugReportReceiver.ACTION)

registerReceiver(BugReportReceiver(), ifl)

}

}

Project C -- (BroadcastTest3):

class BugReportReceiver : BroadcastReceiver() {

companion object {

const val TAG = "BugReportReceiver"

const val ACTION = "com.yu.hu.action.BUGREPPORT"

const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"

}

override fun onReceive(context: Context?, intent: Intent?) {=

val value = intent?.getStringExtra("test")

Log.d(TAG, "onReceive: msg = $value")

Toast.makeText(context, "msg2 = $value", Toast.LENGTH_SHORT).show()

}

}

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

registerReceiver(BugReportReceiver(), IntentFilter(BugReportReceiver.ACTION))

}

}

点击Button后输出结果:

2020-07-10 12:51:27.155 25951-25951/com.example.broadcasttest1 D/MainActivity: send BroadcastReceiver with permission

2020-07-10 12:51:27.157 31322-31336/? W/BroadcastQueue: Permission Denial: receiving Intent { act=com.yu.hu.action.BUGREPPORT flg=0x10 (has extras) } to ProcessRecord{3b20417 25865:com.example.boradcasttest3/u0a164} (pid=25865, uid=10164) requires com.yu.hu.permissions.BUGREPORT due to sender com.example.broadcasttest1 (uid 10155)

2020-07-10 12:51:27.161 25907-25907/com.example.broadcasttest2 D/BugReportReceiver: onReceive: msg = test

可以看到只有B收到了广播了而C没有收到,因为B在AndroidManifest.xml中申请了权限,而C没有,所以报了Permission Denial的错误。在C中也申请了权限后就同样能接收到广播了。

带权限的接收

这种方式可以用来限制发送广播的一方,只有申请了相应的权限才能成功发送广播。使用这种方式权限需要声明在广播接收器的注册方。

Project A -- (BroadcastTest1): - 申请权限

package="com.example.broadcasttest1">

...

class MainActivity : AppCompatActivity() {

companion object {

const val TAG = "MainActivity"

const val ACTION = "com.yu.hu.action.BUGREPPORT"

const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"

}

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

val button = findViewById(R.id.send_btn)

button.setOnClickListener {

val intent = Intent(ACTION)

intent.putExtra("test", "test")

Log.d(TAG, "send Broadcast with permission")

sendBroadcast(intent)

}

}

}

Project B -- (BroadcastTest2): - 不申请权限

class MainActivity : AppCompatActivity() {

companion object {

const val TAG = "MainActivity2"

const val ACTION = "com.yu.hu.action.BUGREPPORT"

const val PERMISSION = "com.yu.hu.permissions.BUGREPORT"

}

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

val button = findViewById(R.id.send_btn)

button.setOnClickListener {

val intent = Intent(ACTION)

intent.putExtra("test", "test")

Log.d(TAG, "send Broadcast without permission")

//不申请权限发送

sendBroadcast(intent)

}

}

}

Project C -- (BroadcastTest3): - 声明权限并在注册时添加权限

package="com.example.boradcasttest3">

...

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

registerReceiver(BugReportReceiver(), IntentFilter(BugReportReceiver.ACTION), "com.test.permission.receiver", null)

}

}

在A中发送广播:

2020-07-10 14:07:36.187 12843-12843/com.example.broadcasttest1 D/MainActivity: send Broadcast with permission

2020-07-10 14:07:36.191 12600-12600/com.example.boradcasttest3 D/BugReportReceiver: onReceive2: msg = test

成功发送也成功接收处理。下面是在B中发送广播的日志:

2020-07-10 14:08:04.368 13003-13003/com.example.broadcasttest2 D/MainActivity2: send Broadcast without permission

2020-07-10 14:08:04.370 31322-31336/? W/BroadcastQueue: Permission Denial: broadcasting Intent { act=com.yu.hu.action.BUGREPPORT flg=0x10 (has extras) } from com.example.broadcasttest2 (pid=13003, uid=10162) requires com.test.permission.receiver due to registered receiver BroadcastFilter{37dbe8b u0 ReceiverList{7706c5a 12600 com.example.boradcasttest3/10164/u0 remote:8530405}}

发送之后报了Permission Denial,所以接收器没有接收到这条广播。

转载地址:https://blog.csdn.net/weixin_39975900/article/details/117484322 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:android 嵌入web容器,Github最火开源项目-H5和Android通信容器BridgeWebView的使用
下一篇:鸿蒙系统nova3i,华为nova3i无惧大型手游:打造丝般顺滑娱乐体验

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月10日 19时00分20秒