Android 动态权限判断是否允许的几种方式及测试

2023-11-12

一、说在前面

由于各个系统厂商定制,checkSelfPermission在有些机型上是始终为0的(也就是允许),这个问题非常头疼嘞,于是手持一加对三种方式进行了测试。
以read_sms权限为例

二、检查方式

  1. 常用的检查
ContextCompat.checkSelfPermission(context, permission)
println("self权限: $permissionState")
  1. ops系统检查
val op = AppOpsManager.permissionToOp(android.Manifest.permission.READ_SMS)
val appOpsManager = getSystemService(AppOpsManager::class.java)

val result = appOpsManager.noteProxyOp(op, packageName)
println("OPS权限: $result")

3.ops系统检查(方法已过时弃用了)

val appOpsManager = getSystemService(AppOpsManager::class.java)

val checkResult = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_FINE_LOCATION, Binder.getCallingUid(), packageName)
println("OPS2权限: $checkResult")

三、结果条件

  1. PackageManager结果
  1. PERMISSION_GRANTED 0: 允许
  2. PERMISSION_DENIED 1: 未允许
  1. ops结果
  1. AppOpsManager.MODE_ALLOWED 0: 允许
  2. AppOpsManager.MODE_IGNORED 1: 禁止
  3. AppOpsManager.MODE_ERRORED 2: 出错
  4. AppOpsManager.MODE_FOREGROUND 3: 询问
    3.测试代码
 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
//--------------------------------------------------------------------------------
 		val permissionState = checkSelfPermission(android.Manifest.permission.READ_SMS)
        var smg = ""
        when (permissionState) {
            PackageManager.PERMISSION_GRANTED -> smg = "有权限"

            PackageManager.PERMISSION_DENIED -> smg = "未获取权限"

        }
        println("self权限: $permissionState  $smg")

//--------------------------------------------------------------------------------

        val op = AppOpsManager.permissionToOp(android.Manifest.permission.READ_SMS)
        val appOpsManager = getSystemService(AppOpsManager::class.java)

        val result = appOpsManager!!.noteProxyOp(op, packageName)
        var smg1 = ""
        when (result) {
            AppOpsManager.MODE_ALLOWED -> smg1 = "有权限"

            AppOpsManager.MODE_IGNORED -> smg1 = "无权限"

            AppOpsManager.MODE_ERRORED -> smg1 = "检查出错"

            AppOpsManager.MODE_FOREGROUND -> smg1 = "询问"
        }
        println("OPS权限: $result  $smg1")

//--------------------------------------------------------------------------------

        val checkResult = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_FINE_LOCATION, Binder.getCallingUid(), packageName)
        var smg2 = ""
        when (result) {
            AppOpsManager.MODE_ALLOWED -> smg2 = "有权限"

            AppOpsManager.MODE_IGNORED -> smg2 = "无权限"

            AppOpsManager.MODE_ERRORED -> smg2 = "检查出错"

            AppOpsManager.MODE_FOREGROUND -> smg2 = "询问"
        }
        println("OPS2权限: $checkResult  $smg2")

四、打印结果

1. 允许

一加5T 9.0.0
一加6T
华为MATE8 9.0.0
在这里插入图片描述
小米MAX2 7.1.1
在这里插入图片描述

2. 禁止

一加5T
在这里插入图片描述
华为MATE8
在这里插入图片描述
小米MAX2
在这里插入图片描述

3. 询问

一加5T
在这里插入图片描述
小米MAX2 ,小米在这里自动弹出权限申请框

无操作后自动拒绝
在这里插入图片描述
选择允许后
在这里插入图片描述

五、结论

用了两款手机测试,上图很明显,appOpsManager.checkOpNoThrow可以直接废弃了,而另外两种方式可以结合使用进行交叉验证。

  • 方式1在一加上只有允许权限生效了,小米正常(一加上一直如此,大部分系统没问题)

  • 方式2判断非常准确,虽然只辨别出了有和无

  • 权限状态分为三种(允许、禁止、询问)的机型
  • 权限状态分为两种(允许、禁止)的机型
    都可以使用前两种方式交叉验证,下面贴上代码。
		fun hasPermission(context: Context, permission: String): Boolean {
            if (!isOverMarshmallow()) {
                // 系统版本小于6.0的机型
                return true
            }
            //`````````````````````````````````````````````````````````````````
            val permissionState = checkSelfPermission(context, permission)
            println("self权限: $permissionState")

            when (permissionState) {
                PackageManager.PERMISSION_GRANTED -> println("有权限")

                PackageManager.PERMISSION_DENIED -> println("未获取权限")
            }

            //`````````````````````````````````````````````````````````````````

            val op = AppOpsManager.permissionToOp(permission)
            val appOpsManager = context.getSystemService(AppOpsManager::class.java)
            if (appOpsManager == null || TextUtils.isEmpty(op)) {
                return true
            }
            val result = appOpsManager.noteProxyOp(op, context.packageName)
            println("OPS权限: $result")

            when (result) {
                AppOpsManager.MODE_ALLOWED -> println("有权限")

                AppOpsManager.MODE_IGNORED -> println("权限禁止")

                AppOpsManager.MODE_ERRORED -> println("出错了")

                AppOpsManager.MODE_FOREGROUND -> println("权限需要询问")
            }


            return result == AppOpsManager.MODE_ALLOWED && permissionState == PackageManager.PERMISSION_GRANTED
        }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 动态权限判断是否允许的几种方式及测试 的相关文章

随机推荐

  • 一文说清产品经理、项目经理、产品负责人的区别

    以下为译文 原文链接 https nealcabage com product vs project vs program management 太多的团队无法区分Product Manager Product Owner Program
  • SSD 之OP预留空间

    SSD上的OP指的是用户不可操作的容量 大小为实际容量减去用户可用容量 OP区域一般被用于优化操作如 WL GC和坏块映射等 OP一般分三层 见下图 第一层容量固定为SSD标称容量的7 37 这是因为标称容量采用千进制为单位 而NAND颗粒
  • 并行编程——OpenMP

    文章目录 并行机体系结构 并行机体系结构及通信机制 并行程序 设计方法 设计模型 openmp 基础 OpenMp简介 在VS中启用OpenMP OpenMp并行编程模型 OpenMp 存储模型 支持条件编译 并行化控制 编译制导 功能指令
  • 小扎亲自官宣Meta视觉大模型!自监督学习无需微调,多任务效果超OpenCLIP丨开源...

    萧箫 发自 凹非寺量子位 公众号 QbitAI 无需文字标签 完全自监督的Meta视觉大模型来了 小扎亲自官宣 发布即收获大量关注度 在语义分割 实例分割 深度估计和图像检索等任务中 这个名叫DINOv2的视觉大模型均取得了非常不错的效果
  • feign get方法参数是form提交方式

    使用feign调用服务端接口时如果服务端接口是get方式 并且采用form方式表达提交的时候需要使用 SpringQueryMap 注解 但是参数列表中只能使用一个 SpringQueryMap注解 多个只会有一个生效 服务端 被调用方 c
  • 全球及中国动脉导管未闭治疗设备行业渠道模式分析与需求前景预测报告2022版

    全球及中国动脉导管未闭治疗设备行业渠道模式分析与需求前景预测报告2022版 修订日期 2021年12月 搜索鸿晟信合研究院查看官网更多内容 2021年 全球动脉导管未闭治疗设备市场规模达到了 百万美元 预计2027年可以达到 百万美元 年复
  • 理事的三板斧-以项目部为例

    作为管理者来说 无非是理事 管人 这中间理事尤为重要 因为事理的不清楚 人肯定难管好 即使有个人魅力 队伍凝聚力强 事理的不对 也会事倍功半 长期的去看 团队也会出问题的 事理的清楚 我认为主要有三点 目标 流程 模板 目标清楚了 方向就不
  • 跨度计算算法

    int FindingSpans int inputArray int spans new int inputArray length for int i 0 i lt inputArray length i int span 1 int
  • 关于matplotlib及相关cmap参数的取值

    关于matplotlib及相关cmap参数的取值 在matplotlib中对于图片的显示有如下方法 这不是重点 其中有cmap binary 的参数 plt imshow imgs i reshape 28 28 cmap binary 或
  • Linux系统之安装java开发环境

    Linux系统之安装java开发环境 一 java介绍 1 java简介 2 java的三大平台 3 java的主要特性 二 检查本地系统环境 1 检查系统版本 2 检查系统内核版本 三 清空java环境 1 删除java目录 2 移除所有
  • 不高兴的津津1073

    Description 津津上初中了 妈妈认为津津应该更加用功学习 所以津津除了上学之外 还要参加妈妈为她报名的各科复习班 另外每周妈妈还会送她去学习朗诵 舞蹈和钢琴 但是津津如果一天上课超过八个小时就会不高兴 而且上得越久就会越不高兴 假
  • 经典Proxool.properties

    数据库1jdbc 1 proxool alias WEBGISjdbc 1 proxool driver class oracle jdbc driver OracleDriverjdbc 1 proxool driver url jdbc
  • JNLP 文件无法打开的解决办法

    JNLP Java Network Launching Protocol 是 java 提供的一种可以通过浏览器直接执行 java 应用程序的途径 它使你可以直接通过一个网页上的 URL 连接打开一个 java 应用程序 因此 要运行 jn
  • 用户·角色·权限·表

    一 引言 因为做过的一些系统的权限管理的功能虽然在逐步完善 但总有些不尽人意的地方 总想抽个时间来更好的思考一下权限系统的设计 权限系统一直以来是我们应用系统不可缺少的一个部分 若每个应用系统都重新对系统的权限进行设计 以满足不同系统用户的
  • React新特性hooks中memo,usememo,useCallback的区别

    useMemo memo类似于PureCompoent 作用是优化组件性能 防止组件触发重渲染 memo针对 一个组件的渲染是否重复执行
  • 江苏开票系统安全接入服务器地址,江苏省增值税发票查询平台网址.doc

    江苏省增值税发票查询平台网址 江苏省增值税发票查询平台网址 81 增值税发票查询平台于2016年5月27日在全国36个省 市 自治区升级完毕 目前全国统一版本为V2 0 00 新版本上线后 功能更加强大和人性化 为了使广大纳税人能更加正确
  • nginx出现 “414 request-uri too large”

    公司项目有一个模块 在请求查询的时候使用了Get方法 由于拼接的url过长 导致nginx出现了 414 request uri too large 错误 出现这种问题可以按照如下解决 在nginx的nginx conf修改如下参数的 cl
  • git check-pick,git patch 与 git stash 详解

    大家好 我是 17 今天和大家聊一聊 git check pick git patch 与 git stash 的用法 git cherry pick 为什么要用 cherry pick 不适合 merge 的场景就可以考虑 cherry
  • mysql数据库——思维导图

    学完mysql后 自己弄得的思维导图 原图30 6MB 太大了放不上来 这里就放个链接吧 欢迎大家去看 如果有需要改正的地方 请告诉我 谢谢 链接 https www zhixi com view 718f3805 密码 6522 下面是M
  • Android 动态权限判断是否允许的几种方式及测试

    一 说在前面 由于各个系统厂商定制 checkSelfPermission在有些机型上是始终为0的 也就是允许 这个问题非常头疼嘞 于是手持一加对三种方式进行了测试 以read sms权限为例 二 检查方式 常用的检查 ContextCom