Android Q 适配指导

一、隐私权:

1、分区存储

       

过滤视图

为了让用户更好地控制自己的文件,减少文件混乱情况,Android Q 更改了应用对设备外部存储设备中的文件(例如存储在路径 /sdcard 下的文件)的访问方式。

如果应用 Android Q 为目标平台,则在访问外部存储设备中的文件时会进入过滤视图,此时只能查看特定目录(Context.getExternalFilesDir())和特定类型的文件

1、 访问自己创建的文件:始终拥有读/写权限,无论文件位于特定目录以内还是以外

2、 访问其他应用创建的文件,需满足:

a)已获得 READ_EXTERNAL_STORAGE 权限

b)文件位于一个明确定义的媒体集合(MediaStore)中:照片 (Images )、视频(Video)、音乐文件(Audio

3、 访问另一应用创建的任何其他文件(包括“downloads”目录下的文件),必须使用存储访问框架(SAF),用户可以通过该框架选择特定文件

SAF文档:使用“存储访问框架”打开文件  |  Android 开发者  |  Android Developers

4、 过滤视图对媒体数据的限制:如未获取新的ACCESS_MEDIA_LOCATION权限,则无法查看照片的位置信息等元数据

  • 情形1:卸载后保留应用的文件

如果应用在访问外部存储设备中的文件时是过滤视图,那么卸载该应用时,系统会清除特定于该应用的目录中的所有文件。

a) 如果需要卸载后保留文件,需要保存到媒体集合( MediaStore )中

b) 需要在应用的AndroidManifest.xml文件增加:<application android:hasFragileUserData="true"/>,否则应用数据会被直接删除,设置后会提示是否删除

  • 情形2:分享媒体文件

某些应用允许用户彼此分享媒体文件。例如,用户可以通过社交媒体应用与朋友分享照片和视频。而分享后可能提示文件不存在。

应用使用路径方式(file:// URI)分享文件,其他应用访问时可能提示文件不存在

建议使用FileProvider适配(content://URI)

2、设备位置

1. Q之前只有ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION;

2. Q新增加了后台定位权限:ACCESS_BACKGROUND_LOCATION,该权限对应始终允许;老的权限:ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION代表仅前台使用允许;

3. 应用的targetSdkVersion<Q,谷歌提供了兼容性方案,只要应用申请了老的位置权限ACCESS_FINE_LOCATION或者ACCESS_COARSE_LOCATION,会默认请求ACCESS_BACKGROUND_LOCATION权限,动态授权弹框参考:

4. 应用的TargetSdkVersion>=Q,如果应用必须要始终定位,可以只申请ACCESS_BACKGROUND_LOCATION即可;s

如果应用只需要申请前台定位,则只需要申请老的定位权限即可;如果都申请则出现三态权限弹框 

5. 如果用户选择仅前台使用允许,应用的页面退后台,通过启动前台服务让应用处于前台状态,必须把前台服务标为:foregroundServiceType=“location”,才能获取位置信息。

3、后台应用启动

针对在没有用户互动的情况下从后台启动活动的新限制

特性说明:

    Android Q 对应用可启动 Activity 的时间施加了限制。此项行为变更有助于最大限度地减少对用户造成的中断,并且可以让用户更好地控制其屏幕上显示的内容。

只要应用启动 Activity 是因用户互动直接引发的,该应用就极有可能不会受到此项变更的影响。

    允许 Activity 启动的条件

    在 Android Q 上运行的应用只有在满足以下一个或多个条件时才能启动 Activity:

  1. 该应用具有可见窗口,例如在前台运行的 Activity。 
    注意:为了启动 Activity,前台服务不会将应用限定为在前台运行。
  2. 该应用在前台任务的返回栈中具有一项 Activity。
  3. 该应用具有最近启动的 Activity。
  4. 该应用对最近的一项 Activity 调用了 finish()。这仅适用于在调用 finish() 时,应用在前台中具有一项 Activity,或在前台任务的返回栈中具有一项 Activity 的情况。
  5. 该应用的一项服务被系统绑定。该条件仅适用于以下服务(可能需要启动界面):AccessibilityServiceAutofillServiceCallRedirectionServiceHostApduServiceInCallServiceTileServiceVoiceInteractionService 以及 VrListenerService
  6. 该应用的某一项服务被其他可见应用绑定。请注意,绑定到该服务的应用必须在后台对该应用保持可见,才能成功启动 Activity。
  7. 该应用会从系统收到通知 PendingIntent。如果存在针对服务和广播接收器的待定 intent,则该应用可以在待定 intent 发送后启动 Activity 几秒钟时间。
  8. 该应用会收到从其他可见应用发送的 PendingIntent
  9. 该应用会收到系统广播,其中要求应用启动界面。示例包括 ACTION_NEW_OUTGOING_CALL 和 SECRET_CODE_ACTION。该应用可以在广播发送后启动 Activity 并持续几秒钟时间。
  10. 该应用已通过 CompanionDeviceManager API 与配套硬件设备相关联。借助此 API,该应用可以启动 Activity 以响应用户在配对设备上执行的操作。
  11. 该应用是在设备所有者模式下运行的设备政策控制器。示例用例包括完全托管的企业设备,以及数字标识牌和自助服务终端等专属设备
  12. 该应用已获得用户授予的 SYSTEM_ALERT_WINDOW 权限。

4、禁止应用读取Device ID

Q版本将限制应用访问不可重设的设备识别码,如 IMEI、序列号等,所有获取设备识别码的接口都增加了新的权限:READ_PRIVILEGED_PHONE_STATE,该权限需要系统签名的应用才能申请,意味着三方应用无法获取设备识别码

(1)TargetSdkVersion<Q并且没有申请READ_PHONE_STATE权限,或者TargetSdkVersion>=Q,获取device id会抛异常SecurityException;

(2)TargetSdkVersion<Q并且申请了READ_PHONE_STATE,通过getDeviceId接口读取的值为Null;

(3)无法获取到device id,会对应用依赖device id的功能产生影响。

解决方案:

1. 谷歌提供的适配指导文档。

唯一标识符最佳做法:唯一标识符最佳做法  |  Android 开发者  |  Android Developers

官方文档:Android 10 中的隐私权变更  |  Android 开发者  |  Android Developers

2. 开发者可以尝试使用Android ID替换Device ID。

(1)获取代码:Settings.System.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

(2)Android ID和Device ID的区别:

(a)手机恢复出厂设置,Android ID可以重置,但是Device ID无法重置;

(b)对于安装在运行 Android 8.0 的设备上的应用,ANDROID_ID 的值现在将根据应用签署密钥和用户确定作用域。应用签署密钥、用户和设备的每个组合都具有唯一的 ANDROID_ID 值。因此,在相同设备上运行但具有不同签署密钥的应用将不会再看到相同的 Android ID(即使对于同一用户来说,也是如此),具体可参考O版本的变更:https://developer.android.com/about/versions/oreo/android-8.0-changes#privacy-all

老的READ_PHONE_STATE权限整改 

由于获取device id权限的变更,通过申请老的READ_PHONE_STATE已经无法获取device id信息,所以如果应用申请敏感权限READ_PHONE_STATE的目的仅仅是为了获取device id,建议代码中增加版本判断,判断如果仅当运行的手机版本是Q以前的版本,才申请用户动态授权,否则申请的权限没有用

5、MAC 地址

为了进一步保护用户的隐私,Android Q在连接Wi-Fi时,默认启用了Mac地址随机化的特性,如果APP不进行适配,使用原来方式获取到的Mac地址可能是随机生成的,并不是真实的Mac地址。

如果APP需要使用Mac地址作为设备的标识,无论您的Target SDK是否设置为Q,只要运行在Android Q上,您就需要进行适配。

6、访问剪贴板数据

除非应用是默认输入法 (IME) 或是目前处于焦点的应用,否则无法访问剪贴板数据

7、访问 /proc/net 文件系统

Android Q 撤消了 /proc/net 访问权限,其中包含有关设备网络状态的信息。需要访问此信息的应用(如 VPN)应引用 NetworkStatsManager 和 ConnectivityManager 类。

8、摄像头和连接性

针对完整摄像头元数据的访问权限实施了新限制,并且现在许多连接工作流都需要精确位置权限。

9、访问相机信息需要获得权限

Android Q 更改了 getCameraCharacteristics() 方法默认返回的信息的广度。具体而言,您的应用必须具有 CAMERA 权限才能访问此方法的返回值中可能包含的设备特定元数据。

10、对启用和停用 WLAN 的限制

以 Android Q 为目标平台的应用无法启用或停用 WLAN。WifiManager.setWifiEnabled() 方法始终返回 false

11、电话,Wi-Fi,蓝牙API所需的精确位置权限

1. 应用的targetSdkVersion>=Q:除非应用具有ACCESS_FINE_LOCATION权限,否则在Android Q上运行时,应用无法在Wi-Fi,Wi-Fi Aware或蓝牙API中使用多种方法。

2. 应用的targetSdkVersion<Q:不受影响,只需要申请ACCESS_COARSE_LOCATION或者ACCESS_FINE_LOCATION即可

3. 具体影响的接口有:

Telephony

      • requestNetworkScan()
      • onResults()
      • onCellLocationChanged()
      • onCellInfoChanged()
      • onServiceStateChanged()

WLAN

l  WifiManager

        • startScan()
        • getScanResults()
        • getConnectionInfo()
        • getConfiguredNetworks()

l  WifiAwareManager

l  WifiP2pManager

l  WifiRttManager

Bluetooth

l  BluetoothAdapter

        • startDiscovery()
        • startLeScan()
        • LeScanCallback()

二、权限变更

1、限制对屏幕内容的访问

为了保护用户的屏幕内容,Android Q 更改了 READ_FRAME_BUFFERCAPTURE_VIDEO_OUTPUT 和 CAPTURE_SECURE_VIDEO_OUTPUT 权限的作用域,使其只能通过签名访问,从而禁止以静默方式访问设备的屏幕内容。

需要访问设备屏幕内容的应用应使用 MediaProjection API,此 API 会显示提示,要求用户同意声明。

2、面向用户的权限检查(针对旧版应用)

如果您的应用以 Android 5.1(API 级别 22)或更低版本为目标平台,则当用户首次在 Android Q 上运行该应用时,他们会看到一个权限屏幕,如图 1 所示。此屏幕可以让用户撤消系统先前在安装时授予您应用的访问权限。

3、身体活动识别

新增敏感权限:ACTIVITY_RECOGNITION,Android Q为需要检测用户移动的应用程序(例如步行,骑自行车或车辆)引入了新的ACTIVITY_RECOGNITION运行时权限。注意:除非用户已授予您的应用此权限,否则Google Play服务中的某些库(例如活动识别API)不会提供结果。该特性只影响TargetSdkVersion>=Q的应用

三、非SDK接口管控

1、非SDK接口的定义

SDK接口:https://developer.android.com/reference/packages,能查到的接口都是SDK接口;

非SDK接口:除了谷歌开放的SDK接口之外的其他JAVA接口都是非SDK接口。

2、应用滥用非SDK接口的危害

这些非SDK接口在大版本之间的变化可能很频繁,带来兼容性问题。

名单类型

影响

greylist

targetSDK>=P时,警告。

greylist-max-o

targetSDK<P时,警告;>=P时,不允许调用。

greylist-max-p

targetSDK<Q时,警告;>=Q时,不允许调用。

blacklist

所有三方应用不允许调用。

3、影响范围


所有三方应用都可能会受到影响,从名单变化来看,黑名单接口大大增加,Q版本有很多非SDK接口被删除,都会导致应用出现兼容性问题,影响评估很大,需要所有应用排查和整改。

4、检查应用的非SDK接口

  • 构建targetSdkVersion为Q的可调式应用
    • adb logcat  ---- “Accessing hidden field Landroid/os/Message…”
  • 使用StrictMode API
    • detectNonSdkApiUsage() + penaltyListener()
    • 处理onVmViolation回调
  • Veridex静态分析工具
    • AOSP 中提供源代码及预编译可执行文件
    • 跟随每次Q Beta 版本发布更新
    • 不支持JNI调用,对反射调用的检测结果不完全准确

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/121654349