Android适配Q版本Beta2
背景
谷歌API LEVEL要求,应用2019上架谷歌Play商店需要应用升级自己的targetSdkVersion到28。具体参考
本次主要改动点:
1、TargetSdkVersion>=28。
2、适配Android Q系统
升级TargetSdkVersion到28
1、Apache HTTP 客户端弃用
取消了对 Apache HTTP 客户端的支持。
要继续使用 Apache HTTP 客户端,以 Android 9 及更高版本为目标的应用可以向其 AndroidManifest.xml 添加以下内容:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
2、强制执行 FLAG_ACTIVITY_NEW_TASK 要求
在 Android 9 中,您不能从非 Activity 环境中启动 Activity,除非您传递 Intent 标志 FLAG_ACTIVITY_NEW_TASK
。 如果您尝试在不传递此标志的情况下启动 Activity,则该 Activity 不会启动,系统会在日志中输出一则消息。
适配Android Q系统
1、应用存储空间限制
Android Q 在外部存储设备中为每个应用提供了一个“隔离存储沙盒”(例如 /sdcard)。任何其他应用都无法直接访问您应用的沙盒文件。由于文件是您应用的私有文件,因此您不再需要任何权限即可在外部存储设备中访问和保存自己的文件。
谷歌官方推荐应用在沙盒内存储文件的地址为Context.getExternalFilesDir()下的文件夹。比如要存储一张图片,则应放在Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)中。
以下将按访问的目标文件的地址介绍如何适配:
-
访问自己文件:Q中用更精细的媒体特定权限替换并取消了
READ_EXTERNAL_STORAGE
和WRITE_EXTERNAL_STORAGE
权限,并且无需特定权限,应用即可访问自己沙盒中的文件。 -
访问系统媒体文件:Q中引入了一个新定义媒体文件的共享集合,如果要访问沙盒外的媒体共享文件,比如照片,音乐,视频等,需要申请新的媒体权限:
READ_MEDIA_IMAGES,READ_MEDIA_VIDEO,READ_MEDIA_AUDIO
,申请方法同原来的存储权限。可使用 MediaStore API(Android 2.3(API 级别 9)引入),或者存储访问框架 (SAF)方式读取(Android 4.4(API 级别 19)引入了存储访问框架 (SAF)) - 1.因为对于TargetSdkVersion<Q的应用,谷歌提供了兼容方案,所以不适配也不 会有权限问题。 2.TargetSdkVersion>=Q的应用,需要适配增加新的存储权限申请,否则会报权 限问题:
-
访问系统下载文件:对于系统下载文件夹的访问,暂时没做限制,但是,要访问其中其他应用的文件,必须允许用户使用系统的文件选择器应用来选择文件。
关于存储权限的(如何启用)影响范围
-
在Android Q Beat1中,谷歌暂未开放存储权限的改动。我们需要使用adb命令
adb shell sm set-isolated-storage on
-
当满足以下每个条件时,将开启兼容模式,即不开启Q设备中的存储权限改动:
1、应用targetSDK<=P。 2、应用安装在从 Android P 升级到 Android Q 的设备上。
但是当应用重新安装(更新)时,不会重新开启兼容模式,存储权限改动将生效。 所以按官方文档所说,无论targetSDK是否为Q,必须对应用进行存储权限改动的适配。
经过测试,对SD卡其他目录的读写操作,在操作的时候,会统一被转换到沙箱内,因此目前不受影响。
即SD卡上只会存在两个目录:
/Android/data/com.ccc.news/
/Android/sanbox/com.ccc.news/
获取App目录
Context.getDataDir()
Context.getFilesDir()
Context.getCacheDir()
获取App SD目录
Context.getExternalFilesDir()
Context.getExternalCacheDirr()
获取SD卡目录(设备<Q),沙箱目录(设备>=Q)
Environment.getExternalStorageDirectory()
建议使用 Context.getDataDir() 或者 Context.getExternalFilesDir()
不再使用 Environment类 获取外部路径
但在获取设备上其他文件时,无法通过路径操作文件,需要修改获取方式(MediaStore API,或存储访问框架 (SAF)方式)
端内已确定需要修复的功能:
1、评论功能,评论添加图片
2、个人中心,反馈上传图片
3、首页快速登录功能,判断微博是否启动过(预装版已关闭该功能,主版本需要修改)
2、禁止应用读取设备标识符信息
禁止获取device id和serial
从 Android Q 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE
权限(需要系统签名才能申请)才能访问设备的不可重置标识符(device id和serial)。
- 对于 TargetSdkVersion < Q且没有申请
READ_PHONE_STATE
权限的应用和TargetSdkVersion >= Q的全部应用,获取device id会抛异常SecurityException。 - 对于 TargetSdkVersion < Q 且申请了
READ_PHONE_STATE权
限的应用,通过getDeviceId接口读取的值为Null。 -
获取serial 的值为unknown
P设备上:
没有READ_PHONE_STATE权限,getDeviceId 抛出SecurityException,可以拿到serial
有READ_PHONE_STATE权限,可以拿到DeviceId,serial
Mac地址随机化(针对wifi探针)
6.0以后的android系统getMacAddress();这个api已经失效。目前端内均使用该方式获取mac地址,均为02:00:00:00:00:00
TargetSdkVersion < Q。
在Q系统的手机上,获取不到deviceId,serial获取到的值为unknow。
在<Q系统的手机上,可以拿到serial,需要READ_PHONE_STATE权限,才能拿到DeviceId。
3、后台地理位置权限
Android Q 引入了新的位置权限 ACCESS_BACKGROUND_LOCATION
。会影响应用在后台运行时对位置信息的访问权。如果应用需要在后台时也获得用户位置,就需要动态申请该权限。
- targetSDK <= P 应用如果请求了
ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION
权限,Q设备会自动帮你申请ACCESS_BACKGROUND_LOCATION
权限。
targetSDK >= Q才会生效,暂时不需要修改
4、非SDK管控(Hidden API)
统计新增P版本的10w+个接口被加入了目前Q版本的黑名单;
参考:https://blog.csdn.net/ccc20134/article/details/90055247
使用非SDK 接口,目前只会打印相关日志,不会引起功能问题
5、禁止应用后台弹页面
目前版本只是弹toast提示开发者需要整改的页面,未开启禁止功能,需要开发者自查和整 改,后面的版本会真的禁止
6、启用和禁用Wi-Fi的限制
在Android Q上运行的应用无法启用或停用Wi-Fi。
7、安装应用接口废弃
申请android.permission.REQUEST_INSTALL_PACKAGES权限,通过FileProvider使用content:// URI安装
8、录音变更(并发录音、三方录音source管控)
录音焦点抢占改动。抢占规则:只是限制不敏感音源无法抢占敏感音源,其他情况都可以随意抢占
9、禁止悬浮窗
在 Android Q(Go 版本)设备上运行的应用不具有 SYSTEM_ALERT_WINDOW
权限。
如果 Go 设备上的应用发送具有 ACTION_MANAGE_OVERLAY_PERMISSION
操作的 Intent,则系统会自动拒绝此请求,并将用户转到设置屏幕,上面会显示不允许授予此权限,原因是它会降低设备的速度。如果 Go 设备上的应用调用 Settings.canDrawOverlays()
,则此方法始终返回 false。
10、折叠屏
1.屏幕比例适配
推荐适配方式:应用支持自适应能力适配
在 manifest 文件的 或 节点中设置 android:resizeableActivity 的值为true,可声明应用支持自适应显 示,Activity 将能以分屏和 freeform 模式启动。
其他方式:设置应用支持的最大比例和最小比例适配
最大宽高比申明: maxaspecratio:2.4(2.4表明在主副屏下满屏显示)
最小宽高比申明: minaspectratio:1.0 (1.0表示在展开态全屏显示)
2.切换显示比例应用不重启适配
在 manifest 文件的 节点中的 android:configChanges 属性增加 screenSize|smallestScreenSize|screenLayout字符串,当屏幕 比例变化时,系统会回调 Activity 的 onConfigurationChanged() 方法,而避免 Activity 重新启动。
通过接口newConfig.screenHeightDp和 newConfig.screenWidthDp获取屏幕尺寸信息调整页面布局
参考资料:
https://developer.android.google.cn/about/versions/pie/android-9.0-changes-28
https://developer.android.google.cn/preview/behavior-changes-all