MENU

android 10 [API 29]适配指南

December 9, 2019 • Read: 795 • Android

非SDK接口

google 针对非SDK接口的限制

非SDK接口检测工具

官方给出了一个检测工具,下载地址:veridex
veridex使用方法:
appcompat.sh --dex-file=apk.apk

blacklist、greylist、greylist-max-o、greylist-max-p含义

以上截图中,blacklist、greylist、greylist-max-o、greylist-max-p含义如下:

blacklist 黑名单:禁止使用的非SDK接口,运行时直接Crash(因此必须解决)
greylist 灰名单:即当前版本仍能使用的非SDK接口,但在下一版本中可能变成被限制的非SDK接口
greylist-max-o: 在targetSDK<=O中能使用,但是在targetSDK>=P中被禁止使用的非SDK接口
greylist-max-p: 在targetSDK<=P中能使用,但是在targetSDK>=Q中被禁止使用的非SDK接口

设备ID

从Android 10开始已经无法完全标识一个设备,曾经用mac地址、IMEI等设备信息标识设备的方法,从Android 10开始统统失效。而且无论你的APP是否是配过Android 10。

IMEI等设备信息

从Android10开始普通应用不再允许请求权限android.permission.READ_PHONE_STATE。而且,无论你的App是否适配过Android Q(既targetSdkVersion是否大于等于29),均无法再获取到设备IMEI等设备信息

受影响的API

Build.getSerial();
TelephonyManager.getImei();
TelephonyManager.getMeid();
TelephonyManager.getDeviceId();
TelephonyManager.getSubscriberId();
TelephonyManager.getSimSerialNumber();

targetSdkVersion<29 的应用,其在获取设备ID时,会直接返回null
targetSdkVersion>=29 的应用,其在获取设备ID时,会直接跑出异常SecurityException

如果您的App希望在Android 10以下的设备中仍然获取设备IMEI等信息,可按以下方式进行适配:

<uses-permission
        android:name="android.permission.READ_PHONE_STATE"
        android:maxSdkVersion="28" />

Mac地址随机分配

从Android10开始,默认情况下,在搭载 Android 10 或更高版本的设备上,系统会传输随机分配的 MAC 地址。(既从Android 10开始,普通应用已经无法获取设备的真正mac地址,标识设备已经无法使用mac地址)

唯一ID的替代

Google给出的解决方案是:如果您的应用有 追踪非登录用户重装 的需求,可用ANDROID_ID来标识设备。

ANDROID_ID的生成规则为:签名+设备信息+设备用户
ANDROID_ID重置规则:设备恢复出厂设置时,ANDROID_ID将被重置

String androidId = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);

也就是从Android 10开始已经无法完全标识一个设备,曾经用mac地址、IMEI等设备信息标识设备的方法,从Android 10开始统统失效。而且无论你的APP是否是配过Android 10。

外部存储

为了使用户更改的管理Sdcard中的文件,解决文件混乱的问题。从Android 10开始(API level 29),Android将对外部存储进行一定的限制。默认情况下,对于外部存储,App只能通过Context.getExternalFilesDir()访问自己的特定文件目录;以及系统特定的文件类型目录(例:照片、屏幕快照、视频 等)。

着重说一下存储

1、Android Q为每个应用程序在外部存储设备提供了一个独立的存储沙箱,应用直接通过文件路径保存的文件都会保存在应用的沙箱目录,另外应用卸载的时候默认所有应用沙箱目录是会被删除。

2、共享集合:不希望应用卸载删除的文件,需要应用通过MediaProvider或者SAF的方式保存在公共共享集合目录,公共集合目录包括:多媒体文件集合(音频、视频和图片)以及下载文件集合。

3、权限变更:应用读写自己沙箱和共享集合目录中应用自己的文件是不需要申请任何权限的,但是如果应用需要读取其他应用生成的多媒体文件就需要申请权限:

(1)读取其他应用存放在共享集合的图片和视频文件,就需要分别申请READ_MEDIA_IMAGES和READ_MEDIA_VIDEO权限,具体要申请哪个权限取决于应用需要访问的文件类型;

(2)读取其他应用存放在共享集合的音乐类型文件,就需要申请READ_MEDIA_AUDIO权限;

(3)读取其他应用生成的多媒体文件,需要通过MediaProvider的接口读取,无法直接通过文件路径读取;

(4)系统只提供了多媒体文件的读权限,没有提供写权限,应用无法通过申请写权限修改其他应用生成的文件;

(5)下载目录的文件没有增加对应的权限,读取下载目录的文件需要通过SAF的方式读取。

4、写其他应用的多媒体文件,需要通过申请成为默认系统图库和音乐应用,或者让用户主动授权的方式实现。

5、需要读写指定的任意目录的文件只能通过SAF的方式实现。

APP专属路径

对于App专属 内部存储路径与外部存储路径的访问,将不再需要 READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE 权限:

内部存储路径 /data/data/<包名>/
外部存储路径 /storage/Android/data/<包名>/

手机共享路径

读取其他APP创建的共享文件,例:相册、屏幕快照 等,则需要申请READ_EXTERNAL_STORAGE权限:

图片:Photos、Screenshots 使用MediaStore.Images API访问
视频 使用MediaStore.Video API访问
音频 使用MediaStore.Audio API访问

Downloads文件夹

读取手机的Downloads文件夹,不需要任何权限,需要使用API Storage Access Framework

权限相关

主要包括:

  • 在后台运行时访问设备位置信息
    Android 10 引入了 ACCESS_BACKGROUND_LOCATION 权限。若应用在后台运行时,访问手机位置,需要动态申请该权限,用户则可以选择拒绝。官方给出的数据,大部分用户对位置信息是比较敏感的。而且大部分用户是不允许应用在后台使用位置信息的。
  • 从后台启动 Activity 的限制
  • 屏幕录制
    不需要手动申请权限,但官方 API内部会向用户弹窗申请权限
  • 摄像头和麦克风
    Android 9 摄像头和麦克风 后台权限已经移除了

活动探知——新增权限

在访问用户步数或其他物理活动类别是需要获取运行时权限

剪切板隐私限制

从Android P开始,除非你的应用是默认输入法,否则它无法访问用户的剪贴板数据;但向剪切板写入数据不影响。