一.安卓权限简介: 安卓将哪些权限需要动态申请:将权限分为正常权限和危险权限,正常权限不涉及用户隐私,只需要在manifest中声明即可,比如网络,NFC等,另一类则是危险权限,涉及到用户隐私信息,需要动态授权后才能使用,比如sd卡读写,联系人,短信等。 1.使用权限的工作流
2.安卓应用权限有助于保护用户的受限数据和受限操作,比如系统状态和用户的联系信息,拍照/录制视频等行为。Android权限从请求时机可以分为安装时权限(一般权限、签名权限)、运行时权限、特殊权限。
(1)一般权限:此类权限允许访问超出应用沙盒的数据和执行超出应用沙盒的操作,但对用户隐私和其他应用的运行构成的风险很小。系统会为一般权限分配 normal 保护级别
(2)签名权限:当应用声明了其他应用已定义的签名权限时,如果两个应用使用同一证书进行签名,系统会在安装时向前者授予该权限。否则,系统无法向前者授予该权限。说的很具体点就是:具体来说,当一个应用声明某个权限时,如果这个权限是签名权限类型,那么只有那些用同一个开发者密钥签名的应用才能授予和使用这个权限。开发者密钥是一个唯一的密钥,用于在发布时对应用程序进行签名,确保应用的完整性和来源的可信性。
(3)运行时权限:也是危险权限,运行时权限必须动态申请,protectLevel == dangerous,比如相机,录音,获取联系人等
关于运行时权限的注意:
1)在请求之前解释其用途只请求你需要的权限,满足最小特权原则;
2)减少请求的次数;
3)或者用intent来代替,让其系统或其他应用来处理;
4)在具体使用到的业务功能处才能申请对应权限,且必须详细说明用途,不能提前申请权限;
(4)特殊权限:一般是平台和设备制造商定义,(显示悬浮窗权限、修改系统设置、忽略电池优化等等)比如设定精准的闹钟,在应用前方显示和绘图,访问所有存储数据
二.安卓各大版本的权限API
这小节将详细介绍安卓各大版本权限相关的API的区别
1.历代版本变化:
Android 1.0 (API Level 1)
最初引入了基本的权限管理机制。应用在安装时需要声明所需的权限,用户在安装时必须同意所有请求的权限。
Android 1.5 (Cupcake, API Level 3)
没有显著的权限变化。
Android 2.2 (Froyo, API Level 8) 增加了对权限请求的改进,如新增权限 ACCESS_WIFI_STATE。
Android 4.1 (Jelly Bean, API Level 16) READ_EXTERNAL_STORAGE 权限被引入用于访问外部存储。
Android 4.3 (Jelly Bean, API Level 18) 引入了一些新的权限,如 BLUETOOTH_ADMIN 和 NFC.
Android 4.4 (KitKat, API Level 19) 新增了一些权限,比如 READ_LOGS 和 SYSTEM_ALERT_WINDOW 变得更加严格。
Android 5.0 (Lollipop, API Level 21) 新增了多种权限,比如 BODY_SENSORS 用于访问健康数据。 引入了运行时权限的概念,允许应用仅在需要时请求某些权限。 从1.0到5.0版本,可以看到android从最开始的不需要任何权限到不断完善各项功能的权限,不断的做出提升与优化。 1)用户在安装时获取到所有权限,在使用权限时无需进行预判断。 2)如果用户手动来到设置将权限关闭,我们的项目在用到该权限时会发生Crash,所以如果使用低版本权限管理,请将需要用到权限的地方try-catch起来。 3)低版本权限提示弹窗都是手机厂商自定义的。他们拥有系统权限,在检测到你的App使用权限时会提示用户权限授权,如果用户拒绝则替用户到设置中心关闭权限。
Android 6.0 (Marshmallow, API Level 23)
引入了运行时权限模式,大幅改变权限管理机制:
用户可以在应用运行时授予或拒绝特定权限。
增加了 REQUEST_PERMISSIONS API, 用于动态请求权限,引入权限组的概念
1)将权限分为了普通权限和隐私权限,普通权限在清单文件中声明则直接获取。隐私权限也需要在清单文件中声明,但是在安装完成后,所有的隐私权限都为拒绝状态,需要在用到隐私权限时判断权限是否开启,否则项目直接发生Crash。比如常用的隐私权限:相机、定位、打电话、短信、读写存储、麦克风录音、传感器
上图中有一个权限群的概念,同一组的任何一个权限被授权了,其他权限也自动被授权。
例如,一旦WRITE_EXTERNAL_STORAGE被授权了,APP同时也就有了READ_EXTERNAL_STORAGE权限。
2)readphonestate变为危险权限,需要用户主动授权才可使用。在适配Android10.0之后,READ_PHONE_STATE权限直接被取消掉了,换成了系统权限 READ_PRIVILEGED_PHONE_STATE ,此权限只能在系统App中才可以被使用。而如果代码处理上仍使用READ_PHONE_STATE权限进行授权的话,手机上不会再弹出同样的权限授予弹窗了,此时如果仍调用 getDeviceId 方法,会直接抛出 SecurityException
Android 7.0 (Nougat, API Level 24)
对运行时权限模型进行了进一步的改进。
应用自提升权限变得更加严格。
为了提高私有目录的安全性,防止应用信息的泄漏,从 Android 7.0 开始,应用私有目录的访问权限被做限制。具体表现为,开发人员不能够再简单地通过 file:// URI 访问其他应用的私有目录文件或者让其他应用访问自己的私有目录文件。会触发 FileUriExposedException的错误异常。
解决办法:使用FileProvider
Android 8.0 (Oreo, API Level 26) 引入后台位置限制,限制应用在后台访问位置数据的能力。 新增权限组划分,例如 SYSTEM_ALERT_WINDOW 需要用户手动授予。 在Android 8之前,如果应用在运行时请求权限并且被授予该权限,系统后错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。对于Android 8的应用,该行为已经被纠正,系统只会授予应用明确请求的权限。然而一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。 例如,假设某个应用在其清单中列出READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE。应用请求READ_EXTERNAL_STORAGE,并且用户授予了该权限,如果该应用针对的是API级别24或更低级别,系统还会同时授予WRITE_EXTERNAL_STORAGE,因为该权限也属于STORAGE权限组并且也在清单中注册过。如果该应用针对的是Android 8,则系统此时仅会授予READ_EXTERNAL_STORAGE,不过在该应用以后申请WRITE_EXTERNAL_STORAGE权限时,系统会立即授予该权限,而不会提示用户。
Android 9.0 (Pie, API Level 28) 更加严格地限制应用访问设备的唯一标识符,如 IMEI 和序列号。 前台服务权限:新增 FOREGROUND_SERVICE 权限,应用必须声明该权限才能使用前台服务。限制非活动应用对设备麦克风和摄像头的访问。
Android 10 (API Level 29) 背景定位权限:引入了 ACCESS_BACKGROUND_LOCATION 权限,应用需要单独请求才能在后台访问位置信息。 存储权限:新的 Scoped Storage 模型,引入了对外部存储访问的更细粒度控制。 Android 11 (API Level 30) 一次性权限:用户可以授予一次性权限,应用仅在当前使用过程中可以访问敏感数据(如位置、麦克风、相机)。 选中的照片和视频、全部照片和视频、不允许。也就是所谓的三态位置权限。 自动权限重置:进一步改进,未使用的应用会自动重置敏感权限。 范围存储增强:继续优化Scoped Storage,实现更严格的访问控制。 从Android6到Android11,可以看到安卓从引入了运行时权限模式,改善了权限管理机制到引入“仅次一次”的权限机制,可以看出android系统的权限机制在不断的完善与向保护用户隐私、提升用户体验方向进步。 Android 12 (API Level 31) 近似位置权限:引入 ACCESS_COARSE_LOCATION 和 ACCESS_FINE_LOCATION 的更细粒度控制,应用可以请求近似位置而不是精确位置。 麦克风和相机指示灯:当应用使用麦克风或相机时,状态栏会显示指示灯。 隐私仪表板:用户可以查看哪些应用在何时访问了敏感权限。
Android 13 (API Level 33) 引入了"通知"权限,应用需要获得用户同意才能发送通知。 更细粒度的媒体访问权限:新增独立的 READ_MEDIA_IMAGES、READ_MEDIA_VIDEO 和 READ_MEDIA_AUDIO 权限,用于分别访问图片、视频和音频文件。
Android 12 13都在进一步完善对敏感权限获取的优化:从两个方面,既需要保证用户隐私,又不影响用户正常功能的使用。
Android 14(API Level 34)
进一步细化权限管理,增强用户隐私保护和开发者体验。
Android14系统上 target sdk 版本低于23的应用无法安装,已有的应用将继续保持安装状态
2.作用域存储:
重点来了解分区存储的原理及适配
2.1.作用域存储![file]
app保存文件或缓存数据应遵循的原则:
1)不要随意占用用户内置存储
2)不要随意在sd卡上新建目录,应该放在自己应用包名对应的外置存储目录下,卸载APP时可以被清除。
3)磁盘空间有上线,并按照一定的策略进行清除。
2.2.作用域存储适配:
2.2.总结:
1.在android 11及以上适配访问所有文件的权限:
(1)在manifest添加;
在标签下添加如下字段: android:requestLegacyExternalStorage="true" 这一部是为了兼容Android10 的系统,给开发者一个过度,可以不强制开启分区存储。但是在android11及以后版本仍然需要适配。
(2)如果需要访问共享存储空间,则判断运行设备版本是否大于等于Android6.0,若是则需要申请WRITE_EXTERNAL_STORAGE 权限。拿到权限后,通过Uri访问共享存储空间里的文件。如果需要访问其它目录,则通过SAF访问
(3)如果想要做文件管理器、病毒扫描管理器等功能。则判断运行设备版本是否大于等于Android 6.0,若是先需要申请普通的存储权。若运行设备版本为Android 10.0,则可以直接通过路径访问/sdcard/目录下文件(因为禁用了分区存储);若运行设备版本为Android 11.0,则需要申请MANAGE_EXTERNAL_STORAGE 权限。 三.安卓应用隐私合规问题总结: 隐私合规是什么?在客户端,权限隐私就是权限和隐私两大方面,权限在行为,隐私在数据。
- 应用权限最佳做法:
2. 隐私权准则:
谷歌将隐私数据分为“位置”、“个人信息”、“财务信息”、“网络历史记录”、“联系人”等,不同隐私数据类型对应大量数据类型。
3. 常见合规问题总结:
(1).违规收集个人信息:
-
1)APP隐私政策必须非常清楚、全面地说明(不要用可能收集、了解用户信息这种模糊不清晰的词语)收集用户个人信息的目的、方式和范围,用户个人信息包括但不限于mac地址、设备序列号、imei、imsi、软件安装列表、通讯录信息、短信信息等。
-
2) 在用户浏览完隐私政策并点击同意按钮前,APP和SDK不要有任何收集行为或者关联动作,例如和服务器之间发送或者接收信息的行为。
-
3)隐私协议用户同意环节,必须明确使用“同意”、“拒绝/不使用”按钮,不要使用“好的”、“明白”、“我知道了”这种模糊性词语。
(2).超范围收集个人信息:APP或SDK在APP运行时,不要在后台按频率收集用户的个人信息(位置信息、imei、mac地址等),如果需要收集必须在隐私政策中做出详细说明按频率收集信息的目的方式范围,且经过用户同意和不能超出实现服务的合理范围。
(3).违规使用个人信息:APP或SDK在APP运行时,不要在后台将收集到的用户个人信息(位置信息、imei、mac地址等)未经用户同意发送给第三方SDK或者服务器,如果需要必须在隐私政策中做出详细说明为什么要将收集到的信息发送给第三方,且经过用户同意和不能超出实现服务的合理范围。
(4).强制用户使用定向推送功能:APP如果存在个性化推送或精准营销服务,必须在隐私政策中做出非常全面清晰的说明,说明收集用户的哪些任何信息(用户搜索、浏览记录、使用习惯等),如何运用到个性化推送或精准营销功能,如何保护用户的信息安全,并且必须有明确的关闭此功能的开关。注意此功能开关必须和APP正常消息开关有明显的区别。
(5).APP强制、频繁、过度索取权限:
APP没有对应的服务或场景时,不要申请对应权限(例如没有使用到位置的服务时,不要申请定位权限);APP申请权限时,如果用户拒绝,不要直接退出APP无法使用;APP申请权限时,如果用户拒绝,非用户主动触发功能,不要反复弹出申请权限窗口,影响用户使用。
注意:推荐用户不会自主使用的文件,比如调用相机、录音等产生的临时文件,建议存储到私有目录下,请勿调用储存权限
注意:仅在多选场景下,可使用自定义相册UI获取存储权限后供用户选择;其余场景,比如单选,建议更换为不需要存储权限的方案
(6).APP频繁自启动和关联启动:APP不要随意在手机后台自启动或者在运行时关联启动其它APP,如果需要后台启动或者关联启动,一定要在隐私政策里面非常清楚、全面地说明,为什么需要自启动或者关联启动,什么情况下会触发自启动和关联启动,且必须经过用户同意。
(7).为用户注销账户等个人信息相关服务设置障碍:APP必须含有用户信息更改、删除个人信息和注销账号的功能,用户进行账号注销时,不要设置不合理条件,例如3个月无异常登录记录,且未更换手机或者邮箱等。APP用户注销、个人信息安全投诉、举报渠道的处理承诺时限不要超过15个工作日。
(8).欺骗误导下载APP,APP信息明示不到位:APP如果存在广告下载APP页面,不要用含有隐藏条件的诱导方式引导用户点击下载,并且广告页面必须有明确的下载按钮,用户仅在点击按钮区域才能触发下载操作,下载过程必须有暂停、取消下载功能,APP必须在页面有明确的信息5要素(APP名称、APP版本、APP开发者、APP权限使用列表、APP隐私政策协议)
(9).欺骗误导收集个人信息:
APP不要以积分、奖励、优惠等方式欺骗误导用户提供身份证号码以及个人生物特征信息。
4.隐私合规检测实践:
如何进行项目对敏感API的调用检查:一般分为静态检查和动态检查。静态检查:一般可以基于项目依赖的字节码扫描,基于apk的smali扫描,lint检查。动态检查一般是xposed方案、基于transform的字节码修改方案。比如transform的方案流程:打包构建APK时,执行gradle脚本,调用插件库,动态替换已有项目内代码请求隐私权限或敏感信息收集的API,输出已替换API列表等相关日志信息。其中基本流程:
5、如何进行合规化处理tips:
- (1).用户交互层面**:** 1)申请权限弹窗申明
2)同意隐私协议不能默认勾选;个性化推荐支持关闭
3)权限弹窗控制频次:比如第一次弹起申请相机的权限,用户拒绝后,第二次尽量不能再弹窗申请,以影响用户最小成本去处理,比如toast
4)同意隐私协议不能默认勾选 5)在未使用任何功能的情况,查看是否有弹窗索取手机存储权限。预期效果:不进行弹窗索取手机存储权
- (2).数据传输方面: 接口请求不携带敏感信息:明文传输手机号、imei ,oaid