谷歌针对的Q预览版的特性分享,内容涉及比较多。遗憾的是没有提供PPT给参会者,如下内容根据提纲与回忆整理,如有缺失敬请谅解。
适配Q重点归纳
android Q发布时间表
禁止无用户交互的后台启动activity。
在后台,通过Notification也可以启动activity,但是通过alarm定时器无法启动activity。
允许Activity Starts的条件:
从 Android Q 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 签名权限才能访问设备的不可重置标识符(包含 IMEI 和序列号)。
原来的READ_PHONE_STATE权限已经不能获得IMEI和序列号,如果想在Q设备上通过如下代码获得设备ID,会返回空值(targetSDK<=P)或者报错(targetSDK==Q)。
((TelephonyManager) getActivity()
.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()
IMEI 可以帮我们判断用户是否更换了设备。在 Android Q 里有没有合适的替代方案?
Android 官方唯一标识符最佳做法:
官方文档:https://developer.android.google.cn/preview/privacy/scoped-storage
如下是Q Beta3版本的最新特性,目前网上大部分基于Beta1的存储分区解释有差异,以如下Beta3特性为准。
外部存储沙盒:
Android Q 在外部存储设备中为每个应用提供了一个“隔离存储沙盒”(例如 /sdcard)。任何其他应用都无法直接访问您应用的沙盒文件。卸载APK时也会删除SD卡沙盒内的数据,要想在卸载后保留文件,请将它们保存到MediaStore中.
访问自己文件:
当应用target Q时,它会进入分区存储模式,这意味着它不再能直接访问/sdcard。尝试直接访问将导致FileNotFoundException或EPERM错误。
可以无需任何权限,直接访问应用所属沙盒目录(例如Context.getExternalFilesDir()),要想访问沙盒目录以外的文件,需要使用MediaStore或存储访问框架SAF。
访问媒体文件:
要访问沙盒外的媒体共享文件,比如照片,音乐,视频等,需要通过MediaStore。MediaStore以外的文件需要通过系统的文件选择器应用来进行访问。
所有应用都可以在没有任何权限的情况下为MediaStore提供内容,但是要查看其他应用提供的内容,必须获取READ_EXTERNAL_STORAGE权限。
Metadata:
android Q开始,应用需要获取ACCESS_MEDIA_LOCATION权限才可以访问媒体文件的位置信息元数据。
MediaStore中的LATITUDE和LONGITUDE字段已废弃,请使用ExifInterface来替代。
适配:
当应用target Q时,默认会开启分区存储模式;Q以下,默认情况下,应用储存方式将不会发生任何改变,依旧采用与旧版本 Android 系统相同的储存机制。
主动开启或关闭分区特性,使用allowExternalStorageSandbox标签:
<manifest ... >
<application android:allowExternalStorageSandbox="false" ... >
</application>
</manifest>
明年的下个版本,与target SDK级别无关,所有应用都要支持分区存储。
Android 官方文档:https://developer.android.google.cn/preview/privacy/device-location
新增位置权限:ACCESS_BACKGROUND_LOCATION
除非应用的某个 Activity 可见或应用正在运行前台服务,否则应用将被视为在后台运行。如果应用需要在后台时也获得用户位置(比如滴滴),就需要动态申请ACCESS_BACKGROUND_LOCATION权限。
targetSDK <= P 应用如果请求了ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION权限,Q设备会自动帮你申请ACCESS_BACKGROUND_LOCATION权限。
Android 官方文档:https://developer.android.google.cn/preview/non-sdk-q#greylist-now-restricted
在 Android Q 中,受限制的非 SDK 接口数量更多了,建议您在开发时选用相等功能的公开 SDK 接口。为了帮助您成功过渡,并防止应用出现崩溃等问题,仅当应用的目标平台为 Android Q 时,这些限制才会生效。
名单 | 描述 | 影响 |
---|---|---|
白名单 | 公开SDK | |
浅灰名单 | 我们检测到有应用在使用的接口 | 允许访问,可能加入警告或日志 |
深灰名单 (maxTargetSDK = P) |
"接近"浅灰名单的接口,并在android新版本中已经增加了公开替代接口 | 当应用的targetSDK在P或者更早时,允许访问,否则(Q以后)禁止访问 |
黑名单 | 我们认为没有应用在使用的非SDK接口 | 禁止访问,抛出运行时错误 |
Jetpack官方文档:https://developer.android.google.cn/jetpack
主要更新:使用函数生成UI。
正常开发界面是xml布局+code,二者耦合。使用jetpack可以用代码生成UI,无需xml。
具体参看谷歌文档,需要使用Kotlin进行代码生成UI。
折叠屏官方文档:https://developer.android.google.cn/preview/features/foldables
折叠屏适配比较细化,主要是折叠、展开时,在onConfigurationChanged()做界面调整,支持拖拽等,请需要适配的APP模块自行参阅谷歌文档吧。
类似于我们现在的全屏手势,建议今后采用原生实现逻辑;建议应用不要覆盖系统手势,否则可能导致手势冲突。
GSI通用系统映像是未经修改的 Android 开源项目 (AOSP) 代码编译出的“纯 Android”,是一个system.img,适用8.x后支持treble的机型。
GSI的意义:节约时间,提前适配。在没有pixel手机刷Q Beta的情况下,可以使用完全支持treble的机器刷Q GSI,体验Q的新特性。
刷GSI步骤:(适用pixel,其他具体咨询芯片商)
启动到 fastboot 模式,然后解锁bootloader。
通过刷写 vbmeta.img 停用验证启动 (AVB):
$ fastboot --disable-verification flash vbmeta vbmeta.img
清空系统分区,然后将 GSI 刷写到系统分区:
$ fastboot erase system
$ fastboot flash system system.img
擦除用户数据:$ fastboot -w
重新启动:$ fastboot reboot
官方文档:https://source.android.google.cn/setup/build/gsi
从 Android Q 开始,多个路径不再采用常规文件形式,而是采用符号链接形式。如果应用一直以来依赖的都是采用常规文件形式的路径,则可能会出现故障:
/system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
/system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
/system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
/system/bin/linker -> /apex/com.android.runtime/bin/linker
为了确保兼容性,新符号链接会基于旧路径提供,例如 /system/lib/libc.so 现在是指向 /apex/com.android.runtime/lib/bionic/libc.so 的符号链接,等等。因此,dlopen(“/system/lib/libc.so”) 会继续工作,但当应用尝试通过读取 /proc/self/maps 或类似项来检测已加载的库时,将会发现不同之处。这并不常见,但我们发现一些应用会将这种做法作为对抗黑客攻击的一项举措。如果是这样,则应该将新的 /apex/… 路径添加为 Bionic 文件的有效路径。
从 Android Q 开始,系统二进制文件和库会映射到只执行(不可读取)内存,作为应对代码重用攻击的安全强化技术。有意或意外读入已标记为只执行的内存段会抛出 SIGSEGV,无论此读入行为是来自错误、漏洞还是有意的内存自省都不例外。
您可以通过检查 /data/tombstones/ 中的相关 tombstone 文件来确定崩溃是否由变更改所导致。与只执行相关的崩溃包含以下中止消息:
Cause: execute-only (no-read) memory access error; likely due to data in .text.
要解决此问题,开发者可以通过调用 mprotect() 将只执行内存段标记为“读取+执行”,例如用于执行内存检查。不过,我们强烈建议您事后将其重新设为只执行,因为这样可以更好地保护您的应用和用户。
对 ptrace 的调用不会受到影响,因此 ptrace 调试也不会受到影响。
以 Android Q 为目标平台的不受信任的应用无法再针对应用主目录中的文件调用 exec()
。这种从可写应用的主目录执行文件的行为违反了 W^X。应用应该仅加载嵌入到应用的 APK 文件中的二进制代码。
此外,以 Android Q 为目标平台的应用无法针对已执行 dlopen()
的文件中的可执行代码进行内存中修改。这包括含有文本重定位的所有共享对象 (.so
) 文件。
在 Android Q(Go 版本)设备上运行的应用无法获得 SYSTEM_ALERT_WINDOW
权限。这是因为绘制叠加层窗口会使用过多的内存,这对低内存 Android 设备的性能十分有害。
如果在搭载 Android 9 或更低版本的 Go 版设备上运行的应用获得了 SYSTEM_ALERT_WINDOW
权限,则即使设备升级到 Android Q 也会保留此权限。不过,尚不具有此权限的应用在设备升级后便无法获得此权限了。
如果 Go 设备上的应用发送具有 ACTION_MANAGE_OVERLAY_PERMISSION
操作的 intent,则系统会自动拒绝此请求,并将用户转到设置屏幕,上面会显示不允许授予此权限,原因是它会减慢设备的运行速度。如果 Go 设备上的应用调用 Settings.canDrawOverlays()
,则此方法始终返回 false。同样,这些限制不适用于在设备升级到 Android Q 之前便已收到 SYSTEM_ALERT_WINDOW
权限的应用。
作者:十八砖
原文:https://www.jianshu.com/p/df35a2e91d31