Android 通知访问权限

问题背景

客户反馈手机扫描三方运动手表,下载app安装后,通知访问权限打不开。
点击提示“受限设置” “出于安全考虑,此设置目前不可用”。
在这里插入图片描述

问题分析

1、setting界面搜“授予通知访问权限”,此按钮灰色不可点击,点击提示“受限设置” “出于安全考虑,此设置目前不可用”。
2、“授予通知访问权限”界面在setting中的notification_access_permission_details.xml
按钮类型: RestrictedSwitchPreference
对应controller: ApprovalPreferenceController
updateState中跟踪按钮状态

public void updateState(@NonNull String packageName, int uid, boolean isEnableAllowed, boolean isEnabled) {mHelper.updatePackageDetails(packageName, uid);if (mAppOpsManager == null) {mAppOpsManager = getContext().getSystemService(AppOpsManager.class);}final int mode = mAppOpsManager.noteOpNoThrow(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,uid, packageName);final boolean ecmEnabled = getContext().getResources().getBoolean(com.android.internal.R.bool.config_enhancedConfirmationModeEnabled);final boolean appOpsAllowed = !ecmEnabled || mode == AppOpsManager.MODE_ALLOWED;if (!isEnableAllowed && !isEnabled) {setEnabled(false);} else if (isEnabled) {setEnabled(true);} else if (appOpsAllowed && isDisabledByAppOps()) {setEnabled(true);} else if (!appOpsAllowed){setDisabledByAppOps(true);}
}

config_enhancedConfirmationModeEnabled这个值是framework写死的值。
mode = mAppOpsManager.noteOpNoThrow这个是根据apk动态变化的。跟踪这个值异常的原因。

3、AppOpsManager.java noteOpNoThrow
AppOpsService.java noteOperation --> noteOperationUnchecked
打开log开关,单编services。

AppOps                           system_server D  noteOperation: package 000 com.huawei.health
AppOps                           system_server D  noteOperation: package 222 com.huawei.health
AppOps                           system_server D  noteOperationUnchecked: package com.huawei.health
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName com.huawei.health op: 119 userId: 0
//默认值是0
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName 222 com.huawei.health AppOpsManager.opToDefaultMode(op): 0
//实际拿到是2
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName 444 com.huawei.health opModes.get(op, AppOpsManager.opToDefaultMode(op): 2
AppOps                           system_server D  noteOperationUnchecked: ops 2
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName com.huawei.health op: 119 userId: 0
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName 222 com.huawei.health AppOpsManager.opToDefaultMode(op): 0
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName 444 com.huawei.health opModes.get(op, AppOpsManager.opToDefaultMode(op): 2
AppOps                           system_server D  noteOperationUnchecked: op 2
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName com.huawei.health op: 119 userId: 0
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName 222 com.huawei.health AppOpsManager.opToDefaultMode(op): 0
LegacyAppOpsServiceInterfaceImpl system_server W   getPackageMode packageName 444 com.huawei.health opModes.get(op, AppOpsManager.opToDefaultMode(op): 2
//reject #2 权限被拒绝 
AppOps                           system_server D  noteOperation: reject #2 for code 119 (119) uid 10243 package com.huawei.health flags: s
AppOps                           system_server D  noteOperationUnchecked: package 555 com.huawei.health

4、AppOpsManager.opToDefaultMode

public static @Mode int opToDefaultMode(int op) {return sAppOpInfos[op].defaultMode;
}
//sAppOpInfos是个内部数组,存的好多权限的默认值
//119 OP_ACCESS_RESTRICTED_SETTINGS 默认0 MODE_ALLOWEDnew AppOpInfo.Builder(OP_ACCESS_RESTRICTED_SETTINGS, OPSTR_ACCESS_RESTRICTED_SETTINGS,"ACCESS_RESTRICTED_SETTINGS").setDefaultMode(AppOpsManager.MODE_ALLOWED).setDisableReset(true).setRestrictRead(true).build()

5、opModes.get(op, AppOpsManager.opToDefaultMode(op): 2
设置2的地方:

   setMode packageName com.huawei.health op: 119 userId: 10243 # java.lang.Throwableat com.android.server.appop.AppOpsService$Op.setMode(AppOpsService.java:637)at com.android.server.appop.AppOpsService.setMode(AppOpsService.java:2006)at com.android.server.appop.AppOpsService.setMode(AppOpsService.java:1973)at android.app.AppOpsManager.setMode(AppOpsManager.java:7609)at com.android.server.pm.InstallPackageHelper.enableRestrictedSettings(InstallPackageHelper.java:2514)at com.android.server.pm.InstallPackageHelper.updateSettingsInternalLI(InstallPackageHelper.java:2493)at com.android.server.pm.InstallPackageHelper.updateSettingsLI(InstallPackageHelper.java:2277)at com.android.server.pm.InstallPackageHelper.commitPackagesLocked(InstallPackageHelper.java:2246)at com.android.server.pm.InstallPackageHelper.installPackagesLI(InstallPackageHelper.java:1120)at com.android.server.pm.InstallPackageHelper.installPackagesTraced(InstallPackageHelper.java:987)at com.android.server.pm.InstallingSession.processApkInstallRequests(InstallingSession.java:547)at com.android.server.pm.InstallingSession.processInstallRequests(InstallingSession.java:536)at com.android.server.pm.InstallingSession.lambda$processPendingInstall$0(InstallingSession.java:295)at com.android.server.pm.InstallingSession.$r8$lambda$tqRjKCgCJYNNnnY7Qw5M5BHLup8(InstallingSession.java:0)at com.android.server.pm.InstallingSession$$ExternalSyntheticLambda2.run(R8$$SyntheticClass:0)at android.os.Handler.handleCallback(Handler.java:958)at android.os.Handler.dispatchMessage(Handler.java:99)at android.os.Looper.loopOnce(Looper.java:243)at android.os.Looper.loop(Looper.java:338)at android.os.HandlerThread.run(HandlerThread.java:67)at com.android.server.ServiceThread.run(ServiceThread.java:46)setPackageMode packageName com.huawei.health op: 119 mode: 2setPackageMode packageModes.put packageName com.huawei.health op: 119 mode: 2

6、安装应用时就设置了限制: InstallPackageHelper.enableRestrictedSettings

    private void enableRestrictedSettings(String pkgName, int appId) {final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class);final int[] allUsersList = mPm.mUserManager.getUserIds();for (int userId : allUsersList) {final int uid = UserHandle.getUid(userId, appId);appOpsManager.setMode(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,uid,pkgName,AppOpsManager.MODE_ERRORED);}}
//调用的地方// Apply restricted settings on potentially dangerous packages.if (installRequest.getPackageSource() == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE|| installRequest.getPackageSource()== PackageInstaller.PACKAGE_SOURCE_DOWNLOADED_FILE) {enableRestrictedSettings(pkgName, pkg.getUid());}...
//PackageInstaller中
/*** Code indicating that the package being installed comes from a local file on the device. A* file manager that is facilitating the installation of an APK file would use this.*/
public static final int PACKAGE_SOURCE_LOCAL_FILE = 3;/*** Code indicating that the package being installed comes from a file that was downloaded to* the device by the user. For use in place of {@link #PACKAGE_SOURCE_LOCAL_FILE} when the* installer knows the package was downloaded.*/
public static final int PACKAGE_SOURCE_DOWNLOADED_FILE = 4;

可以看出,只有当是本地apk文件安装时,才会设置此限制。

解决方案

此弹框主要是为了防止未知来源的apk文件请求权限,正规途径安装不受影响。
用户也可以在应用信息中手动解除限制。
1、打开受限设置
setting—app management—app list—“ xxx Health”—“…”—“allow restricted settings”
这里其实也是调用的setMode MODE_ALLOWED
2、通过play store安装。(或者adb 绕过上面的if就可以)

如何让自己的应用显示在这里

注册action android:name=“android.service.notification.NotificationListenerService”
setting会自动加载进去。

        <!--通知访问权限--><serviceandroid:name=".NotificationListener"android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"android:enabled="true"android:exported="true"><intent-filter><actionandroid:name="android.service.notification.NotificationListenerService" /></intent-filter></service>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/43944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大小端详解

引例 我们知道整形(int)是4个字节&#xff0c;例如随便举个例子&#xff1a;0x01020304&#xff0c;它一共占了四个地址位&#xff0c;01,02,03,04分别占了一个字节&#xff08;一个字节就对应了一个地址&#xff09;。 那么就会有个问题&#xff1a;我们的01到底是存储在高地…

mysql 5.7.44 32位 zip安装

前言 因为研究别人代码&#xff0c;他使用了5.7的 32位 mysql &#xff0c;同时最新的 8.4 64位 mysql 不能用官方lib连接。所以安装这个版本使用&#xff0c;期间有些坑&#xff0c;在这里记录一下。 下载路径 mysql官方路径&#xff1a;https://downloads.mysql.com/archi…

Linux——多线程(五)

1.线程池 1.1初期框架 thread.hpp #include<iostream> #include <string> #include <unistd.h> #include <functional> #include <pthread.h>namespace ThreadModule {using func_t std::function<void()>;class Thread{public:void E…

Redis 7.x 系列【21】主从复制

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 工作原理2.1 建立连接2.2 全量复制2.3 命令传播2.4 增量复制 3. 拓扑架构3.…

Uniapp表单提交

template中&#xff1a; <template><view class""><button class"tianjia" click"tianjia">添加</button><view class"divOne" v-show"a"><text class"guanbi" click"gua…

本地 HTTP 文件服务器的简单搭建 (deno/std)

首发日期 2024-06-30, 以下为原文内容: 在本地局域网搭建一个文件服务器, 有很多种方式. 本文介绍的是窝觉得比较简单的一种. 文件直接存储在 btrfs 文件系统之中, 底层使用 LVM 管理磁盘, 方便扩容. 使用 btrfs RAID 1 进行镜像备份 (一个文件在 2 块硬盘分别存储一份), 防止…

网络通信、BIO、NIO

1. 涉及的网络基础知识 Socket&#xff1a; 操作系统提供的api&#xff0c;介于应用层和tcp/ip层之间的软件层&#xff0c;封装服务器客户端之间网络通信相关内容&#xff0c;方便调用 IO多路复用&#xff1a; &#xff08;I/O Multiplexing&#xff09;是一种IO操作模式&a…

Python 的 metaclass

文章目录 先说结论1. metaclass 的作用2. 主要的执行过程 1. metaclass.__new__2. metaclass.__call__关于 metaclass.__init__ 3. metaclass.__prepare__4. 自动创建 __slots__ 属性4.1 metaclass 的接口类4.2 metaclass conflict 5. Class metaprogramming 先说结论 1. meta…

Java技术栈总结:JVM虚拟机篇

一、Java的四种引用类型 1、强引用 最常见的引用&#xff0c;类似Object obj new Object()、String str “hello”。如果一个对象具有强引用&#xff0c;垃圾回收器绝对不会回收它。即使抛出“OutOfMemoryError”错误&#xff0c;程序终止&#xff0c;也不会随意回收具有强引…

20240710 每日AI必读资讯

&#x1f916;微软&#xff1a;不会像 OpenAI 一样阻止中国访问 AI 模型 - OpenAI 将于周二&#xff08;7 月 9 日&#xff09;开始阻止中国用户访问其 API。 - 微软发言人表示&#xff1a;Azure OpenAI API服务在中国的提供方式没有变化。 - 公司仍然通过部署在中国以外地区…

妙笔生词智能写歌词软件:创新助力还是艺术之殇?

在音乐创作日益普及和多样化的当下&#xff0c;各种辅助工具层出不穷&#xff0c;妙笔生词智能写歌词软件便是其中之一。那么&#xff0c;它到底表现如何呢&#xff1f; 妙笔生词智能写歌词软件&#xff08;veve522&#xff09;的突出优点在于其便捷性和高效性。对于那些灵感稍…

c/c++:牛客小白月赛93

比赛链接 A 生不逢七 题目描述(题目链接添加链接描述)&#xff1a; 睡前游戏中最简单又最好玩的游戏就是这个啦&#xff01; 该游戏规则为&#xff1a;多名玩家轮流报数&#xff0c;当要报的数字中含有 7 或者是 7 的倍数时&#xff08;例如 37&#xff0c;49&#xff09;&…

腾讯又一平台即将停止运营

随着腾讯公司业务和战略的调整&#xff0c;某些业务逐渐退出历史舞台&#xff0c;如“腾讯直播平台NOW”&#xff0c;以及“QQ签到”&#xff0c;“腾讯待办”&#xff0c;“企鹅FM音频平台”等&#xff0c;最近又有一则重磅消息&#xff0c;那就是“腾讯课堂”也即将停止运营。…

类似评论、省市区这种具有层次结构的数据表怎么设计?

业务功能模块 评论、回复模块省市区表 设置一个给每个数据设置一个parent_id 例如&#xff1a; 某个视频下a写了条评论&#xff0c;那a的parent_id就是0;b回复了a&#xff0c;那b的parent_id就是a的id;c回复了b&#xff0c;那c的parent_id就是b的id; 这样&#xff0c;所有评论…

Mosh|初学者 SQL 教程

sql文件链接&#xff1a;链接: https://pan.baidu.com/s/1okjsgssdxMkfKf8FEos7DA?pwdf9a9 提取码: f9a9 在mysql workbench 导入 create_databases.sql 文件&#xff0c;下面是运行成功的界面 快捷方式&#xff1a;全部运行可以同时按下controlcommandenter &#xff0c;或者…

ceph存储

1 存储简介 存储的三种方式包括&#xff1a;块存储、文件存储、对象存储1。此外&#xff0c;还有内存存储、硬盘存储和闪存存储2。 内存存储&#xff1a;临时性数据存储方式&#xff0c;存储速度快&#xff0c;容量有限&#xff0c;通常用来存储正在使用的程序和数据。硬盘存…

【通信协议】八、CDL(Caterpillar Data Link)协议解析

1、协议简介 CDL(Caterpillar Data Link)是caterpillar的通信协议&#xff0c;该品牌发动机ECM与各控制单元进行通信时&#xff0c;采用基于RS-485的物理层规范进行开发的CDL协议进行通信&#xff1b; 2、物理层 信号传输方式&#xff1a;差分信号&#xff08;通过两条线的电…

稀疏建模介绍,详解机器学习知识

目录 一、什么是机器学习&#xff1f;二、稀疏建模介绍三、Lasso回归简介四、Lasso超参数调整与模型选择 一、什么是机器学习&#xff1f; 机器学习是一种人工智能技术&#xff0c;它使计算机系统能够从数据中学习并做出预测或决策&#xff0c;而无需明确编程。它涉及到使用算…

集训 Day 2 模拟赛总结

复盘 7&#xff1a;30 开题 想到几天前被普及组难度模拟赛支配的恐惧&#xff0c;下意识觉得题目很难 先看 T1&#xff0c;好像不是很难&#xff0c;魔改 Kruskal 应该就行 看 T2 &#xff0c;感觉很神奇&#xff0c;看到多串匹配想到 AC 自动机&#xff0c;又想了想 NOIP …

328. 奇偶链表

https://leetcode.cn/problems/odd-even-linked-list/https://leetcode.cn/problems/odd-even-linked-list/ 解题思路&#xff1a; 把第一个和第二个节点分别作为奇数、偶数的头节点&#xff0c;当遇到奇节点&#xff0c;删除&#xff0c;并插入到奇数头节点后&#xff0c;这样…