当前位置: 首页 > news >正文

Android 11权限适配:从‘单次授权’到‘软件包可见性’,一份给老项目的避坑清单

Android 11权限适配:老项目升级的实战避坑指南

当你的老项目终于决定升级到Android 11时,那些陈旧的权限代码就像定时炸弹一样随时可能引爆。作为经历过多次系统升级的老兵,我深知这种升级过程中的痛苦——尤其是当你的targetSdkVersion还停留在石器时代的时候。本文将带你直击三个最致命的权限变更点,用实战经验帮你避开那些让应用崩溃或功能静默失效的深坑。

1. 单次授权:权限管理的全新游戏规则

Android 11彻底改变了位置、麦克风和摄像头权限的授权方式。还记得以前用户只能在"始终允许"和"拒绝"之间二选一吗?现在系统增加了一个"仅限这一次"的选项,这看似微小的变化却对应用逻辑产生了深远影响。

单次授权的核心行为特征

  • 临时访问窗口:当Activity可见时权限有效,转入后台后短时间内仍可访问(具体时长由系统决定)
  • 前台服务例外:如果在Activity可见时启动了相关前台服务,权限会持续到服务停止
  • 随时可撤销:用户可以在系统设置中随时撤回授权,此时应用进程会被终止
// 传统权限请求方式需要调整 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // 现在这里可能会得到单次授权 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE); }

实际案例:我们有一个健身应用,在升级后突然收到大量用户投诉说跑步轨迹记录不全。原因正是我们假设一旦获得位置权限就会持续有效,没有处理单次授权场景。修复方案是在onResume()中检查权限状态,并在必要时重新请求。

关键提示:所有依赖这些权限的功能都需要增加授权状态检查,不能假设一次授权永久有效

2. 后台位置权限:从简单到复杂的进化

Android 11将后台位置权限(ACCESS_BACKGROUND_LOCATION)完全独立出来,形成了更严格的管控机制。这直接影响了需要持续位置跟踪的应用,如运动追踪、家庭安防等场景。

新旧行为对比表

行为特征Android 10及以前Android 11
权限选项"始终允许"直接包含前后台必须分开请求
请求流程可与其他权限同时请求必须单独请求且先有前台权限
用户引导直接弹窗跳转系统设置页
// 正确的递增请求示例 fun requestLocationPermissions() { when { hasBackgroundLocationPermission() -> { // 已有全部权限 } hasForegroundLocationPermission() -> { // 只有前台权限,请求后台权限 requestPermissions(arrayOf(ACCESS_BACKGROUND_LOCATION), REQ_BACKGROUND) } else -> { // 先请求前台权限 requestPermissions(arrayOf(ACCESS_FINE_LOCATION), REQ_FOREGROUND) } } }

踩坑记录:我们最初尝试同时请求前后台权限,结果应用直接崩溃。日志显示系统抛出了SecurityException,这正是Android 11的新限制——禁止混合请求后台位置权限与其他权限。

3. 软件包可见性:那些突然"消失"的应用

这是最隐蔽也最危险的变化。在Android 11上,你的应用默认"看不见"其他应用了,这直接影响了分享、支付、跳转等核心功能,而且失败时没有任何提示!

受影响的典型场景

  • 检查微信是否安装以便启动分享
  • 查询支付宝包信息验证版本
  • 获取设备上所有浏览器列表
  • 通过包名判断特定应用是否存在
<!-- 解决方案:在AndroidManifest中添加queries声明 --> <queries> <!-- 明确声明需要交互的包名 --> <package android:name="com.tencent.mm" /> <!-- 微信 --> <package android:name="com.eg.android.AlipayGphone" /> <!-- 支付宝 --> <!-- 或者通过intent-filter声明 --> <intent> <action android:name="android.intent.action.SEND" /> <data android:mimeType="image/*" /> </intent> </queries>

血泪教训:我们的应用有一个"分享到微博"的功能,在测试时一切正常,因为测试机安装了开发工具。但上线后用户完全无法使用,日志显示queryIntentActivities返回空列表。根本原因就是缺少包可见性声明,而startActivity()调用却依然能工作,这种静默失败最危险。

4. 其他不容忽视的权限细节

除了上述三大变更,Android 11还引入了一些容易被忽略但同样重要的权限调整:

前台服务类型强化

<!-- 访问麦克风或摄像头的前台服务必须声明类型 --> <service android:name=".RecorderService" android:foregroundServiceType="microphone|camera" />

权限自动重置

// 检查用户是否开启了自动重置 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { boolean isWhitelisted = getPackageManager().isAutoRevokeWhitelisted(); if (!isWhitelisted) { // 引导用户前往设置页 Intent intent = new Intent(Settings.ACTION_AUTO_REVOKE_PERMISSIONS); intent.setData(Uri.fromParts("package", getPackageName(), null)); startActivity(intent); } }

电话权限细分

<!-- 获取电话号码需要新增专门权限 --> <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />

5. 实战检查清单

为了确保老项目平稳过渡,建议按照以下步骤系统性地检查权限相关代码:

  1. 全局搜索权限相关代码

    # 在项目目录下执行 grep -r "requestPermissions(" app/src/ grep -r "checkSelfPermission(" app/src/
  2. 重点检查三类敏感权限

    • 位置权限(ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION)
    • 麦克风权限(RECORD_AUDIO)
    • 摄像头权限(CAMERA)
  3. 验证包可见性影响

    • 所有使用PackageManager.queryIntentActivities()的地方
    • 所有显式检查其他应用是否安装的逻辑
    • 分享、支付等跨应用交互功能
  4. 测试边界场景

    • 授予单次授权后转入后台
    • 拒绝两次权限请求后的表现
    • 长时间未使用应用的权限自动重置
  5. 兼容性测试工具

    # 启用特定变更进行测试 adb shell am compat enable FORCE_SCOPED_STORAGE com.your.package adb shell am compat enable FORCE_PACKAGE_VISIBILITY com.your.package

在经历了三个老项目的Android 11升级后,我发现最耗时的不是实现新功能,而是找出那些基于旧版系统假设的隐蔽代码。特别是那些没有崩溃但功能异常的情况,往往需要结合用户反馈和详细日志分析才能定位。建议在升级前先建立完善的监控体系,确保能及时发现生产环境中的权限相关问题。

http://www.rkmt.cn/news/1475011.html

相关文章:

  • 青岛找靠谱防水师傅,老牌防水机构楼长修楼全城快速上门 - 青岛防水品牌推荐
  • TikTok短视频生成工具哪家好?跨境出海如何用 AI 实现爆款视频复刻
  • Orca 2:小语言模型推理能力提升的结构化教学法
  • Flowable任务监听器实战:如何动态分配审批人?以Create监听器为例
  • STM32串口DMA接收数据只收一次?别急着改循环模式,先检查这个中断处理细节
  • 别再复制粘贴了!手把手教你从源码编译安装Google glog到Ubuntu 22.04
  • Umi-OCR终极指南:5分钟掌握免费开源离线OCR文字识别工具
  • 高校课程设计可用的废品回收微信小程序源码(含云函数+完整页面)
  • 博弈论重构PCA:面向加密市场策略建模的特征降维新范式
  • 终极宝可梦随机化工具教程:Universal Pokemon Randomizer ZX 完全指南
  • 武汉品牌首饰回收分级评分榜(2026年6月实测):谁是你的S级选择? - 薛定谔的梨花猫
  • 【2026年6月深度实测】宁波本地防水堵漏企业名录|宁波卫生间屋顶防水维修商家 宁波靠谱防水补漏公司推荐,卫生间免砸砖/外墙/楼顶/地下室/阳光房渗漏修缮靠谱品牌盘点 - 防水空鼓维修家
  • 出国探亲必办!亲属关系公证海牙认证线上办理全攻略与要点 - 速递信息
  • 2026西安黄金回收价格解密 看懂大盘行情,卖黄金比别人多赚钱 - 奢侈品回收测评
  • 2025 年 8 次飞行实测 5 款耳机:谁才是航空旅行与度假的最佳伴侣?
  • 别再手动改参数了!用Comsol参数化扫描,5分钟搞定反应器多工况分析
  • 大连奢侈品黄金回收排名 连锁实体合规 高价变现安全有保障 - 奢侈品回收评测
  • 终极Windows内存清理指南:用Mem Reduct让旧电脑重获新生 [特殊字符]
  • 离线安装dify 1.7
  • Amber模拟含膜体系,从力场选择到盒子设置:我的lipid14/17实战踩坑与避坑全记录
  • ABAP开发避坑指南:获取表字段和内表结构的3种方法对比与实战选型
  • 零基础新手必看:在快马平台轻松创建你的第一个md文件编辑器
  • MAX7219驱动8位数码管:从硬件连接到软件驱动的完整指南
  • STM32 SPI驱动W25Q64避坑指南:从ID读取到跨页写入的完整流程
  • 2026环境试验设备优质厂家解析:高低温/快速温变/三综合/淋雨/沙尘/冲击试验箱专业供应商 - 品牌企业推荐师(官方)
  • 3个高效解锁学术资源场景:Unpaywall浏览器扩展完整实战指南
  • PADS Layout板框倒角设计:从DFM规范到Gerber输出的实战指南
  • 告别HardFault抓瞎!手把手教你给STM32F103装上CmBacktrace错误追踪库(Keil MDK版)
  • 别再找插件了!用H5+的Barcode模块,5分钟搞定App内扫码功能(附完整代码)
  • 近期上海窗帘品牌排行核心维度横评:从资质到交付 - 速递信息