前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 11适配攻略

Android 11适配攻略

作者头像
八归少年
发布2022-06-29 15:49:24
3.9K0
发布2022-06-29 15:49:24
举报
文章被收录于专栏:program

首语

分享一个Github小技巧。不用下载任何软件,也不需要装任何的浏览器插件,你只用在Github的网址中,gitHub后面添加1s,回车就可以在Vscode界面访问项目代码了。来个例子。 原始地址:https://github.com/hujuny/CommunityLibrary Vscode界面地址:https://github1s.com/hujuny/CommunityLibrary

接下来进入今天的主题👉 Android 11。 Android 12预览版从2021年2月开始启动,目前已经发布了Beta Release版本,Final Relase版本预计在今年年底发布。是时候适配一波Android11了,为后面项目适配铺平道路。

介绍

2020年6月11日,Google正式推送了Android 11 Beta版本,同年年9月9日正式发布。系统主要增强了聊天气泡,安全性和隐私性的保护,电源菜单,可以更好的支持瀑布屏,折叠屏,双屏和 Vulkan 扩展程序等。 首先我们项目中的 targetSdkVersion 改为30。开始适配Android 11。

隐私变更

强制执行分区存储机制

为了避免存储空间的读写权限被滥用,手机中存在着大量不明文件,且应用卸载后也没有删除掉。Android 10 中提出了分区存储(Scoped Storage)这一概念。通过添加外部存储访问机制来更好的管理文件。 外部存储使用getExternalStorageDirectory()方法来获取路径存储文件。外部存储访问机制将外部存储空间划分为三部分:

  • 特定于应用的目录。使用getExternalFilesDir()getExternalCacheDir()getExternalMediaDirs()方法访问。无需权限,且卸载应用时会自动删除(在AndroidManifest.xml文件中声明android:hasFragileUserData="true",用户可以选择是否保留)。
  • 媒体集合。照片、视频、音频这类媒体文件。使用MediaStore 访问,无法直接使用File。访问其他应用的媒体文件时需要READ_EXTERNAL_STORAGE权限。
  • 其它目录。使用存储访问框架SAF(Storage Access Framwork)。 简单粗暴的适配办法就是在AndroidManifest.xml文件中添加如下代码来使用旧的存储模式。
代码语言:javascript
复制
 android:requestLegacyExternalStorage="true"

但是这个适配方法在Android 11中已经失效,必须按照存储机制来乖乖适配,不一样的是Android 11允许使用File来访问媒体集合,但是,使用原始文件路径直接访问还是会重定向到MediaStore API,而且会造成性能影响,因为推荐直接使用MediaStore API。 在 Android 11 上,应用无法再访问外部存储中任何其他应用的专用应用特定目录中的文件。 其它细节详见以下文档: Google介绍Scoped Storage的中字视频:https://www.bilibili.com/video/av77198618 Android 11 中的存储更新:https://developer.android.google.cn/about/versions/11/privacy/storage#manage-device-storage

单次授权

从 Android 11 开始,每当应用请求与位置信息、麦克风摄像头相关的权限时,面向用户的权限对话框会包含仅限这一次选项。如果用户在对话框中选择此选项,系统会向应用授予临时的单次授权。

重置权限

如果用户在 Android 11 或更高版本上几个月未与应用互动,系统会自动重置应用的敏感权限。

位置权限

Android 10请求ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION权限表示在前台时拥有访问设备位置信息的权限。在请求弹框还能看到始终允许,Android 11中,取消了始终允许选项,默认不会授予后台访问设备位置信息的权限。 Android 11将后台获取设备位置信息抽离了出来,通过ACCESS_BACKGROUND_LOCATION权限后台访问设备位置信息的权限,需要注意的一点是,请求ACCESS_BACKGROUND_LOCATION的同时不能请求其它权限,否则系统会抛出异常(在没研究Android 11适配的时候,我就已经发现了这个bug,当时以为是系统的bug,还截了两张图,后面仔细查看,找资料才发现是Android 11的变更)。

怎么处理上述问题呢,官方给出的建议是先请求前台位置信息访问权限,再请求后台位置信息访问权限;单独请求后台位置信息访问权限。

软件包可见性

为了最大限度的减少应用获取其它应用的信息、数据,避免数据泄露、病毒软件等不安全隐患,Google将已安装的应用列表视为个人和敏感用户数据,因此Android 11提出了一个新的特性👉软件包可见性。 软件包可见性会影响提供其他应用相关信息的方法的返回结果,如queryIntentActivities()getPackageInfo()getInstalledApplications()。 需要注意的一点是startActivity 方法不受系统软件包可见性行为的影响,queryIntentActivities()查询为false,一样也可以跳转。 如何适配呢?在之前接入微信支付的时候,文档就有提示Android 11 第三方应用无法拉起应用适配,适配方案为在主工程的AndroidManifest.xml 中增加 <queries> 标签。对于其它应用一样,添加包名即可。

代码语言:javascript
复制
<manifest package="com.example.app"> 
  	...
  	// 在应用的AndroidManifest.xml添加如下<queries>标签
    <queries>
        <package android:name="com.tencent.mm" />   // 指定微信包名
        <package android:name="com.eg.android.AlipayGphone" />
    </queries>
  	...
</manifest>

除了直接添加包名的方式外,也可以按intent和provider来添加。

代码语言:javascript
复制
<manifest package="com.yhj.hualin">
    <queries>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="image/jpeg" />
        </intent>

        <provider android:authorities="com.yhj.settings.files" />
    </queries>
    ...
</manifest>

在极少数情况下,如果遇到 <queries> 元素无法提供适当的软件包可见性,您还可以使用 QUERY_ALL_PACKAGES 权限。 使用queries元素需要Android Gradle 插件版本是 4.1及以上,因为旧版本的插件并不兼容此元素,出现"Element queries is not allowed here" 的警告,也可能会导致manifest合并失败。

前台服务

Android 10中,在前台服务访问位置信息,需要在对应的service中添加 location 服务类型。 Android 11中,在前台服务访问摄像头或麦克风,需要在对应的service中添加camera或microphone 服务类型。

代码语言:javascript
复制
<manifest>
    ...
    <service ...
        android:foregroundServiceType="location|camera|microphone" />
</manifest>

当应用程序在后台运行启动前台服务时,前台服务有如下限制:

  • 除非用户已授予ACCESS_BACKGROUND_LOCATION权限,否则 前台服务无法访问位置。
  • 前台服务无法访问麦克风或摄像头。

除非在以下情况可以访问。

  • 该服务由系统组件启动。
  • 该服务通过与应用小部件交互启动。
  • 该服务通过与通知交互来启动。
  • 该服务作为PendingIntent
  • 从不同的可见应用程序发送的启动 。
  • 该服务由在设备所有者模式下运行的设备策略控制器(DPC)应用程序启动。
  • 该服务由提供VoiceInteractionService
  • 该服务由具有START_ACTIVITIES_FROM_BACKGROUND特权权限的应用程序启动 。
SYSTEM_ALERT_WINDOW权限

在 Android 11 中,向应用授予 SYSTEM_ALERT_WINDOW 权限的方式发生了一些变更。这些变更可以让权限的授予更有目的性,从而达到保护用户的目的。 根据请求自动向某些应用授予 SYSTEM_ALERT_WINDOW 权限。 系统会根据请求自动向某些类型的应用授予 SYSTEM_ALERT_WINDOW 权限:

  • 系统会自动向具有 ROLE_CALL_SCREENING 且请求 SYSTEM_ALERT_WINDOW 的所有应用授予该权限。如果应用失去 ROLE_CALL_SCREENING,就会失去该权限。
  • 系统会自动向通过 MediaProjection 截取屏幕且请求 SYSTEM_ALERT_WINDOW 的所有应用授予该权限,除非用户已明确拒绝向应用授予该权限。当应用停止截取屏幕时,就会失去该权限。此用例主要用于游戏直播应用。 这些应用无需发送 ACTION_MANAGE_OVERLAY_PERMISSION 以获取 SYSTEM_ALERT_WINDOW 权限,它们只需直接请求 SYSTEM_ALERT_WINDOW 即可。 MANAGE_OVERLAY_PERMISSION intent 始终会将用户转至系统权限屏幕。 从 Android 11 开始,ACTION_MANAGE_OVERLAY_PERMISSION intent 始终会将用户转至顶级设置屏幕,用户可在其中授予或撤消应用的 SYSTEM_ALERT_WINDOW 权限。intent 中的任何 package: 数据都会被忽略。 在更低版本的 Android 中,ACTION_MANAGE_OVERLAY_PERMISSION intent 可以指定一个软件包,它会将用户转至应用专用屏幕以管理权限。从 Android 11 开始将不再支持此功能,而是必须由用户先选择要授予或撤消哪些应用的权限。此变更可以让权限的授予更有目的性,从而达到保护用户的目的。
REQUEST_INSTALL_PACKAGES权限

在Android 11中当用户开启“安装未知来源应用”的权限,app就会被杀死。该行为与强制分区存储有关,因为持有 REQUEST_INSTALL_PACKAGES 权限的应用可以访问其他应用的Android/obb 目录。 好在用户授予权限之后,虽然app会被杀死,但是安装页面依然会弹出。

电话号码

应用在读取电话号码时,使用 READ_PHONE_STATE 权限。在Android 11中,通过以下电话号码API,必须请求 READ_PHONE_NUMBERS 权限,不再是 READ_PHONE_STATE 权限。

  • TelephonyManager 类和 TelecomManager 类中的 getLine1Number() 方法。
  • TelephonyManager 类中不受支持的 getMsisdn() 方法。
代码语言:javascript
复制
<manifest>
    <!-- 仅在运行 Android 10(API 级别 29)及更低版本的设备上授予 READ_PHONE_STATE 权限 -->
    <uses-permission android:name="READ_PHONE_STATE"
                     android:maxSdkVersion="29" />
    <uses-permission android:name="READ_PHONE_NUMBERS" />
</manifest>
永久SIM标识符

从Android 11开始,通过 getIccId() 方法访问不可重置的ICCID受到限制,该方法会返回一个非空的空字符串,要唯一标识设备上安装的SIM,改用 getSubscriptionId() 方法。除非设备恢复出厂设置,否则此标识符对于SIM是不变的。

Toast

从Android 11开始 ,从后台发送自定义view的Toast消息系统会进行屏蔽。前台使用不受影响。Toast相应的setViewgetView方法也已经废弃不建议使用。 如果要在后台使用,并且希望用户执行某项操作,请使用通知(Notification)。

新功能和API

状态栏

WindowMetrics 是Android 11新增的类,用于获取窗口边界,同样可以用来获取导航栏高度。

代码语言:javascript
复制
 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {

            val wm = getSystemService(Context.WINDOW_SERVICE) as WindowManager
            val windowMetrics=  wm.currentWindowMetrics
            val wi=windowMetrics.windowInsets
            val insets=wi.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars() or WindowInsets.Type.displayCutout())
            Log.e("yhj", "${insets.top}") 
        }
应用签名

从Android 11开始,仅通过v1签名的应用无法在Android 11的设备上安装或更新,必须使用v2或更高版本进行签名。 Android 11 添加了对 APK 签名方案 v4 的支持。此方案会在单独的文件 (apk-name.apk.idsig) 中生成一种新的签名,但在其他方面与 v2 和 v3 类似。没有对 APK 进行任何更改。此方案支持 ADB 增量 APK 安装,这样会加快 APK 安装速度。

无线调试

Android 11开发者选项增加了一个无线调试功能,可以无需USB连接线连接真机进行日常开发调试工作。类似于使用的插件Android ADB WIFI

  • 使用方法

打开手机开发者选项,找到无线调试打开。选择使用配对码配对设备,记下设备上显示的配对码、IP 地址和端口号。Android Studio terminal 运行 adb pair ipaddr:port 。使用第 5 步中的 IP 地址和端口号,最后输入配对码连接。 需要注意的是,电脑和手机必须在同一网络。Platform Tools 版本需大于30.0。可使用 adb --version 查看。 我用小米手机打开无线调试直接提示”由于某个应用遮挡了权限请求界面,因此设置应用无法验证您的回应“,目前还没有解决,有知道解决的大佬留言哈。

兼容性调试工具

以往我们做适配时,需要先将项目中的 targetSdkVersion 改为对应版本,这就导致适配过程中可能受到其它变更的影响,而新增的兼容性调试工具科技让我们在不升级targetSdkVersion的情况下,开启适配。

  • 使用方法

打开手机开发者选项,找到应用兼容性变更选项,点击进入找到需要调试的应用,在变更列表中,找到想要开启或关闭的变更。

这些常量的详细含义参考官方文档:https://developer.android.google.cn/about/versions/11/reference/compat-framework-changes

相机

Android 11 添加了 API 以查询对同时使用多个摄像头(包括前置摄像头和后置摄像头)的支持。 如需在运行应用的设备上检查支持情况,请使用以下方法:

  • getConcurrentCameraIds()可返回摄像头 ID 组合 Set,这些组合可与有保证的数据流组合并发进行流式传输(如果它们是由同一应用进程配置的)。
  • isConcurrentSessionConfigurationSupported()可查询摄像头设备是否可以并发支持相应的会话配置。
AsyncTask

AsyncTask在Android 11已经不建议使用,建议迁移至Kotlin的协程。 此外 Handler未指定 Looper 的构造方法也已不建议使用。

代码语言:javascript
复制
Handler(Looper.getMainLooper())

总结

Android 11的变更还是比较多的,除了上述变更外,还有5G瀑布屏网络连接等其它变更,未列出的变更请参考官方文档:https://developer.android.google.cn/about/versions/11/。 最后,展示一个Android 11小动画🔊。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 首语
  • 介绍
  • 隐私变更
    • 强制执行分区存储机制
      • 单次授权
        • 重置权限
          • 位置权限
            • 软件包可见性
              • 前台服务
                • SYSTEM_ALERT_WINDOW权限
                  • REQUEST_INSTALL_PACKAGES权限
                    • 电话号码
                      • 永久SIM标识符
                        • Toast
                        • 新功能和API
                          • 状态栏
                            • 应用签名
                              • 无线调试
                                • 兼容性调试工具
                                  • 相机
                                    • AsyncTask
                                    • 总结
                                    相关产品与服务
                                    访问管理
                                    访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档