Android13、14特殊权限-应用安装权限适配

Android13、14特殊权限-应用安装权限适配

文章目录

  • Android13、14特殊权限-应用安装权限适配
    • 一、前言
    • 二、权限适配
    • 三、其他
      • 1、特殊权限-应用安装权限适配小结
      • 2、dumpsys package查看获取到了应用安装权限
      • 3、Android权限系统:应用操作管理类AppOpsManager(Android 10)
      • 4、Android13 授予特殊应用权限代码

一、前言

Android13、14 的源码发现一个问题系统签名应用声明了应用安装权限,
但是安装应用的时候还是没有安装应用权限,
需要在原生Settings中的特殊权限设置一次权限打开才有安装应用权限。

本文只介绍解决方法,里面framework的代码是实际项目的修改中拿来的,不是我自己研究的,不做过多分析。

二、权限适配

AndroidManifest.xml 声明权限:

 <!-- Android O(8) needs this permission to install apk --><uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

Android13:

@UnsupportedAppUsage
private static String[] sOpPerms = new String[] {android.Manifest.permission.ACCESS_COARSE_LOCATION,android.Manifest.permission.ACCESS_FINE_LOCATION,...AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
-        AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
+        AppOpsManager.MODE_ALLOWED, // REQUEST_INSTALL_PACKAGESAppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTUREAppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND...
}

可以看到安装应用权限默认不是 MODE_ALLOWED允许状态,设置成允许状态就行。

Android14:

static final AppOpInfo[] sAppOpInfos = new AppOpInfo[]{...new AppOpInfo.Builder(OP_READ_PHONE_NUMBERS, OPSTR_READ_PHONE_NUMBERS, "READ_PHONE_NUMBERS").setPermission(Manifest.permission.READ_PHONE_NUMBERS).setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),new AppOpInfo.Builder(OP_REQUEST_INSTALL_PACKAGES, OPSTR_REQUEST_INSTALL_PACKAGES,"REQUEST_INSTALL_PACKAGES").setSwitchCode(OP_REQUEST_INSTALL_PACKAGES)-    .setPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES).build(),+    .setPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES)+    .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),...}

Android14 把app权限信息封装成AppOpInfo对象了。

从上面代码可以看到安装应用的权限未设置默认模式,添加默认许可即可。
这里的默认许可,也不是所有应用都需要,
而是拥有了安装应用这个特殊权限的应用才默认许可安装应用。

第二种方法

    private void initOpsPermission(Context context) {try {setPackageAppOpsPermission(context, "com.android.bluetooth", AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW);setPackageAppOpsPermission(context, "com.skg.filemanager", AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES);} catch (Exception e) {e.printStackTrace();DebugLog.debug("error = " + e.getMessage());}}//设置特殊权限通过private void setPackageAppOpsPermission(Context context, String packageName, String opsString) {AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);PackageManager manager = context.getPackageManager();int uid = 1;try {ApplicationInfo packageInfo = manager.getApplicationInfo(packageName, 0);uid = packageInfo.uid;} catch (Exception e) {e.printStackTrace();return;}DebugLog.debug("uid = " + uid);mAppOps.setUidMode(opsString, uid, AppOpsManager.MODE_ALLOWED);}

值得注意的是系统签名应用uid=1000的应用,可以设置打开特殊权限,不能关闭特殊权限,
否则应用会崩溃报错,原生设置中关闭签名应用的特殊权限也是会异常崩溃的。
之前看代码,特殊权限好像是根据uid相关的,
如果关闭这个权限,其他使用这个权限的系统签名应用就会有异常。

三、其他

1、特殊权限-应用安装权限适配小结

有两种方式适配修改:

第一种是在framework中设置默认许可。
第二种是在系统代码中设置给与权限。

2、dumpsys package查看获取到了应用安装权限

console:/ #dumpsys package com.debug.filemanager | grep -i installinstallerPackageName=nullinstallerPackageUid=-1installPermissionsFixed=falseandroid.permission.REQUEST_INSTALL_PACKAGES //请求的权限User 0: ceDataInode=1876 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=falseinstallReason=0firstInstallTime=2024-10-21 21:21:37uninstallReason=0install permissions:android.permission.INSTALL_LOCATION_PROVIDER: granted=trueandroid.permission.READ_INSTALLED_SESSION_PATHS: granted=trueandroid.permission.INSTALL_DYNAMIC_SYSTEM: granted=truecom.android.certinstaller.INSTALL_AS_USER: granted=trueandroid.permission.REQUEST_INSTALL_PACKAGES: granted=true  //显示获取到了安装应用的权限
console:/ # 

但是从代码或判断是否获取到安装应用权限是未获取到权限的。

boolean hasInstallPermission = context.getPackageManager().canRequestPackageInstalls();
LogUtil.debug("hasInstallPermission = " + hasInstallPermission);

打印返回是false的。
如果要知道为啥返回的false,就要研究获取权限的流程了。
有兴趣的可以自己看看。

3、Android权限系统:应用操作管理类AppOpsManager(Android 10)

AppOpsManager 是Google在Android4.3里面引进的应用程序操作(权限)的管理类,核心实现类为AppOpsService。

Google对AppOpsManager的说明在:
AppOpsManager
  app op(应用操作)的出现比运行时权限早,最初在没有出现运行时权限的时候,
  应用一旦被安装成功,是会被一次性授予所有需要的权限的,
  所以限制应用权限的唯一方案是使用AppOpsManager。
  但在现在,app op不但覆盖了所有的运行时权限(例如,拍照的app op是OP_CAMERA,
  也有对应的运行时权限Manifest.permission.CAMERA),还添加了一些没有对应运行时权限的操作(例如,读剪贴板的app op是OP_READ_CLIPBOARD,却没有对应的运行时权限)。
  此外,AppOpsManager提供了跟踪记录的功能,以方便开发者了解系统敏感操作的访问记录,
  使用noteOp(String, int, String)/startOp(String, int, String)可以让系统执行记录,
  而使用unsafeCheckOp(String, int, String),系统不会执行记录。
  noteOp/startOp/unsafeCheckOp在记录敏感操作信息的同时,
  还有一个返回值,开发者可以根据这个返回值决定下一步操作。
  
  返回值有:

  1.MODE_ALLOWED:访问者可以访问该敏感操作;2.MODE_IGNORED:访问者不可以访问该敏感操作,但是不会引发crash;3.MODE_ERRORED:访问者不可以访问该敏感操作,会引发crash;4.MODE_DEFAULT:访问者来决定访问该敏感操作的准入规则。

详细介绍:

https://blog.csdn.net/Invoker123/article/details/109176511

4、Android13 授予特殊应用权限代码

Android 权限类别有啥,网上很多是说有普通权限和危险权限,其实是不准确的。

Android 权限分为普通权限,动态权限,特殊权限,私有权限。

https://blog.csdn.net/wenzhi20102321/article/details/143082504

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

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

相关文章

达梦与mssql的order by的区别

在单表简单查询时&#xff0c;mssql和dm8都可以通过查询字段名或别名进行order by mssql和dm8&#xff0c;使用字段名进行order by select emp_ID,emp_Name from Employee order by emp_Name mssql和dm8&#xff0c;使用字段别名进行order by select emp_ID,emp_Name as …

【隐私计算篇】全同态加密应用场景案例(隐私云计算中的大模型推理、生物识别等)

1.题外话 最近因为奖项答辩&#xff0c;一直在忙材料准备&#xff0c;过程非常耗费时间和精力&#xff0c;很难有时间来分享。不过这段时间虽然很忙碌&#xff0c;但这期间有很多新的收获&#xff0c;特别是通过与领域内专家的深入交流和评审过程&#xff0c;对密码学和隐私计算…

今日头条APP移动手机端留痕脚本

这两个的脚本目的是什么呢&#xff1f; 很简单&#xff0c;就是批量访问指定用户的首页&#xff0c;在他人访客记录里面留下你的账户信息&#xff0c;可以让对方访问你的头条&#xff0c;概率下会关注你的头条&#xff0c;目的嘛&#xff0c;这个自己细想&#xff01; 第1个是…

Python实现Android设备录屏功能及停止录屏功能

1、功能概述&#xff1f; 提供源码下载 之前通过ADB命令实现了实时的录屏功能。但是很遗憾&#xff0c;虽然通过adb命令录屏非常方便&#xff0c;但由于权限限制&#xff0c;无法在安卓系统较高的设备上使用。现选择使用另一开源工具来解决这一问题&#xff0c;并记录使用详细…

php基础:数据类型、常量、字符串

语法补充&#xff1a; 每句必须以&#xff1b;结尾 echo&#xff1a;能输出一个以上的字符串&#xff0c;英文逗号隔开 print&#xff1a;只能输出一个字符串并返回1 1.数据类型 php可以自动识别数据类型。 php有5种数据类型&#xff1a;String&#xff08;字符串&#xf…

java jsoup爬虫如何快速获取到html页面的选择器元素

java jsoup爬虫如何快速获取到html页面的选择器元素 一、打开元素选择器二、选定元素三、定位元素位置四、右键 -> copy ->copySelector五、代码中获取 一、打开元素选择器 在java采用jsoup爬虫中&#xff0c;返回的是html页面而不是json字段&#xff0c;就需要使用jsou…

[C++11] 右值引⽤与移动语义

文章目录 左值和右值左值&#xff08;Lvalue&#xff09;右值&#xff08;Rvalue&#xff09;区别 左值引⽤和右值引⽤左值引用&#xff08;Lvalue Reference&#xff09;右值引用&#xff08;Rvalue Reference&#xff09;右值引用的特点 右值引用延长生命周期右值引⽤和移动语…

传输层UDP

再谈端口号 端口号&#xff1a;标识了主机上进行通信的不同的应用程序 在TCP/IP 协议中我们用“源IP”"源端口号" “目的IP”“目的端口号” “协议号”五元组来标识一个通信 用netstat -n 查看 查看网络信息&#xff0c;我们有两种命令查看网络通信1.用netsta…

Linux-练习3

题目&#xff1a; 操作过程&#xff1a; 1.建立用户组 shengcan&#xff0c;其id 为 2000 2.建立用户组 caiwu&#xff0c;其id 为 2001 3.建立用户组 jishu&#xff0c;其 id 为 2002 4.建立用户 lee&#xff0c;指定其主组 id 为 shengchan&#xff0c;附加组为 jishu 和…

多GPU训练大语言模型,DDP, ZeRO 和 FSDP

在某些时候&#xff0c;我们可能需要将模型训练扩展到单个 GPU 之外。当模型变得太大无法适应单个 GPU 时&#xff0c;需要使用多 GPU 计算策略。但即使模型适合单个 GPU&#xff0c;使用多个 GPU 来加速训练也是有好处的。即使您正在处理一个小模型&#xff0c;了解如何在多个…

HTML5新增属性

1、HTML5 1.1 新增布局标签 header&#xff1a;用于定义文档或者section的页眉&#xff1b;footer&#xff1a;用于定义页面或section的底部信息&#xff1b;nav&#xff1a;用于定位页面上的导航链接部分&#xff1b;article&#xff1a;用于定位文档或者页面中的独立部分&a…

在浏览器中运行 Puppeteer:解锁新能力

Puppeteer&#xff0c;这个强大的浏览器自动化工具&#xff0c;通常在Node.js环境中运行。但你有没有想过&#xff0c;在浏览器本身中运行Puppeteer会是什么样子&#xff1f;这不仅能让我们利用Puppeteer的功能完成更多任务&#xff0c;还能避开Node.js特定的限制。 支持的功…

【Canvas与桌面】文山甲密铺桌面壁纸 1920*1080

【成图】 不加蒙版的部分截图&#xff1a; 加上蒙版的桌面壁纸图&#xff1a; 不加蒙版的桌面壁纸图&#xff1a; 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8&qu…

ts:对象数组的简单使用

ts中对象数组的简单使用 一、主要内容说明二、例子1、源码12、源码1运行效果 三、结语四、定位日期 一、主要内容说明 平常ts创建数组的格式如下&#xff1a; let array:string[]["元素1","元素2","元素3","元素3","元素4"…

在 Ubuntu 22.04 LTS 上安装 NVM (Node Version Manager) 管理和切换不同版本的 Node.js npm

安装 nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash# nvm --version 0.40.1安装 Node.js 的不同版本 列出所有可用的 Node.js 远程版本 nvm ls-remotenvm install v18.20.4# node --version v18.20.4# nvm current v18.20.4npm 是 …

Java语言-异常

目录 1.异常的概念与体系结构 1.1 异常的概念 1.2 异常的体系结构 1.3 异常的分类 1.3.1 编译时异常(受查异常) 1.3.2 运行时异常(非受查异常) 2.异常的处理 2.1 防御式编程 2.1.1 LBYL 2.1.2 EAFP 2.2 异常的抛出 2.3 异常的捕获 2.3.1 异常声明throws 2.3.2 …

gin入门教程(6):全局中间件,自定义中间件

在 Gin 中&#xff0c;中间件用于处理请求的预处理和后处理&#xff0c;可以实现日志、身份验证、跨域资源共享&#xff08;CORS&#xff09;等功能。下面是如何使用和创建中间件的基本步骤&#xff1a; 1. 使用内置中间件 Gin 提供了一些内置中间件&#xff0c;例如&#xf…

Docker 下备份恢复oracle

1.docker导出容器镜像 ##docker save -o 导出后的镜像名称.tar 容器名称|镜像id docker save -o oracle_11g.tar 3fa112fd3642 2.下载镜像上传镜像略 3.加载镜像 ##docker load -i <archive_file> docker load -i oracle11g11201.tar 4.添加版本号…

LeetCode 3185.构成整天的下标对数目 II:哈希表

【LetMeFly】3185.构成整天的下标对数目 II&#xff1a;哈希表 力扣题目链接&#xff1a;https://leetcode.cn/problems/count-pairs-that-form-a-complete-day-ii/ 给你一个整数数组 hours&#xff0c;表示以 小时 为单位的时间&#xff0c;返回一个整数&#xff0c;表示满足…

Spring IoC DI

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 目录 1. 应用分层 1.1 如何分层: 1.2 MVC与三层架构区别联系 2. Spring 3.IoC & DI⼊⻔ 3.1 什么是IoC&#xff1f; 3.2 DI 介绍 …