最近在开发过程中遇到一个需求,就是跨进程的广播通信,一番尝试之后发现首先好像静态注册广播的方式行不通了,因为在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,所以接收器没有接收到这条广播。

android动态注册广播权限,记动态注册广播权限问题相关推荐

  1. android的动态注册,Android应用开发之BroadcastReceiver(广播)的静态注册和动态注册 --Android开发...

    本文将带你了解Android应用开发之BroadcastReceiver(广播)的静态注册和动态注册 --Android开发,希望本文对大家学Android有所帮助 BroadcastReceiver ...

  2. android 注册动态广播 注销_动态注册和注销BroadcastReceiver

    Android广播机制 一.Android广播机制介绍 广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的. Android中广播的是操作系统中产生的各种各样的事件 ...

  3. android 静态广播无效,Android8.0静态广播接收静态注册无效,并实现全局网络监听...

    解决方案: 在APP的Activity中对广播接收进行动态注册即可完成. public class NetWorkStateReceiver extends BroadcastReceiver { @ ...

  4. Android权限之动态权限

    安卓系统的权限管理机制从API 23 (也就是Android 6.0 又叫做 Android M,)之后发生了比较大的改变,在一些比较危险的权限上要求必须申请动态权限,即使你在AndroidMainf ...

  5. Android 6.0及以上版本动态申请权限,11权限

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {//安卓11文件权限// 先判断有没有权限if (Environment.isExter ...

  6. Unity Android 之 Unity Android 交互(aar形式)动态申请权限功能实现(权限可人为怎加删减,并含代码工程)

    Unity Android 之 Unity Android 交互(aar形式)动态申请权限功能实现(权限可人为怎加删减,并含代码工程) 目录

  7. Android 英语单词本英语单词记单词有登陆注册界面Android studio编译

    Android 英语单词本英语单词记单词有登陆注册界面Android studio编译 样例图: 项目视频: Android 单词本英语单词记单词有登陆注册界面,Android studio编译 项目 ...

  8. 广播接收器动静态注册

    广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够收到该广播,并在内部处理相应的逻辑.注册广播的方式一般有两种,在代码中注册和在AndroidManifest. ...

  9. Android中对静态壁纸和动态壁纸原理深入理解

    本章主要内容: 讨论动态壁纸的实现. 在动态壁纸的基础上讨论静态壁纸的实现. 讨论WMS对壁纸窗口所做的特殊处理. 本章涉及的源代码文件名及位置: WallpaperManagerService.ja ...

  10. vue实现用户登录验证 + 权限验证 + 动态路由(左侧菜单栏)

    1. 技术栈说明 vue2.6 + vue-router + vuex + element-ui 2. 开始:新建项目 前提条件:在个人电脑上安装好nodejs(我的是14.15.1)之后,利用nod ...

最新文章

  1. 推荐一位在BAT大厂工作的技术+美女双料博主
  2. 云计算开发技术,Python自动化运维开发实战三部分
  3. 一起学nRF51xx 18 -  蓝牙协议栈烧录
  4. iOS应用崩溃日志分析 iOS应用崩溃日志揭秘
  5. 程序员进阶之路:四个程序员职业阶段,通常对应不同的薪资待遇!
  6. [原]sencha touch之表单(login demo)
  7. python爬虫实例100例-python 爬虫实例
  8. [深度学习] ImageAI库使用笔记
  9. 【iOS开发】生成Appicon图标、为iOS应用添加图标
  10. python编写poc_Poc编写
  11. EXCEL地理工具--小O地图EXCEL插件0705版 2022.4.28发布
  12. 上市公司杰创智能携手甄云,启动供应链采购数字化升级
  13. DeFi 入门必备:你需要了解的 DeFi 重要词语
  14. 借用该函数验证哥德巴赫猜想:任意一个大的偶数都可以分解成两个素数之和。
  15. Handlebars.js的下载及使用示例
  16. 【web前端开发 | CSS】页面布局之盒子模型
  17. 对于Java8的新特性,应该了解(掌握)的哪些
  18. sap 获取计划订单bapi_【原创】2011.09.18 SAP 订单中修改订单净价
  19. java下载我的世界1.11_我的世界Java版1.11
  20. java实战:邮件群发推广微信公众号(一),内含java操作mail.jar和activateon.jar

热门文章

  1. Linq之Lambda进阶
  2. 「代码随想录」139.单词拆分【动态规划】【完全背包】力扣详解!
  3. hdu 1003 Max Sum 简单动态规划
  4. 教你如何创建第一个Java应用程序
  5. 如何使用Movavi Video Editor制作幻灯片?
  6. Android提供两个常用的消息弹出框【Toast和Alert】
  7. 公共技术点之 Android 动画基础
  8. Upgrade to Spring Boot 1.4
  9. 屌丝giser成长记-研一篇(上)
  10. linux的引导过程和服务控制