Android 10(API 级别 29)引入了一些功能和行为变更,以更好地保护用户的隐私。这些变更扩展了用户对其数据以及他们向应用授予的功能的透明度和控制权。这些功能可能意味着您的应用依赖的特定行为或数据与旧版平台相比可能会表现不同。如果您的应用遵循处理用户数据的当前最佳实践,则对您应用的影响应该很小。
此页面列出了每个变更的摘要。
主要变更
本节包含 Android 10 中与隐私相关的关键变更。
外部存储访问范围限定为应用文件和媒体
默认情况下,目标平台为 Android 10 或更高版本的应用可获得对外部存储的范围访问权限,或称范围存储。此类应用无需请求任何与存储相关的用户权限即可查看外部存储设备中的以下类型的文件:
- 使用
getExternalFilesDir()
访问的应用特定目录中的文件。 - 应用从媒体存储区创建的照片、视频和音频剪辑。
要详细了解范围存储以及如何在外部存储设备上共享、访问和修改已保存的文件,请参阅有关如何管理外部存储中的文件和访问和修改媒体文件的指南。
后台访问设备位置需要权限
为了支持用户对应用访问位置信息的额外控制,Android 10 引入了ACCESS_BACKGROUND_LOCATION
权限。
与ACCESS_FINE_LOCATION
和ACCESS_COARSE_LOCATION
权限不同,ACCESS_BACKGROUND_LOCATION
权限仅影响应用在后台运行时对位置的访问。除非满足以下条件之一,否则应用被认为正在后台访问位置:
- 属于应用的 Activity 可见。
应用正在运行已声明为前台服务类型为
location
的前台服务。要在应用中声明服务的“前台服务类型”,请将应用的
targetSdkVersion
或compileSdkVersion
设置为29
或更高版本。详细了解前台服务如何继续需要访问位置的用户启动操作。
如果您的应用创建和监控地理围栏并以 Android 10(API 级别 29)或更高版本为目标,则必须声明ACCESS_BACKGROUND_LOCATION
权限。
以 Android 9 或更低版本为目标时自动授予访问权限
如果您的应用在 Android 10 或更高版本上运行,但以 Android 9(API 级别 28)或更低版本为目标,则平台会应用以下行为:
- 如果您的应用为
ACCESS_FINE_LOCATION
或ACCESS_COARSE_LOCATION
声明了<uses-permission>
元素,则系统会在安装过程中自动添加ACCESS_BACKGROUND_LOCATION
的<uses-permission>
元素。 - 如果您的应用请求
ACCESS_FINE_LOCATION
或ACCESS_COARSE_LOCATION
,则系统会自动将ACCESS_BACKGROUND_LOCATION
添加到请求中。
设备升级到 Android 10 时的访问权限
如果用户向您的应用授予访问设备位置的权限(ACCESS_COARSE_LOCATION
或ACCESS_FINE_LOCATION
),然后将其设备从 Android 9 升级到 Android 10,则系统会自动更新授予您的应用的一组基于位置的权限。升级后您的应用接收到的权限集取决于其目标 SDK 版本及其已定义的权限,如下表所示:
目标平台版本 | 粗略或精确 授予权限? |
后台权限 在清单文件中定义? |
更新默认权限状态 |
---|---|---|---|
Android 10 | 是 | 是 | 前台和后台访问 |
Android 10 | 是 | 否 | 仅前台访问 |
Android 10 | 否 | (系统忽略) | 无访问权限 |
Android 9 或更低版本 | 是 | 在设备升级时由系统自动添加 | 前台和后台访问 |
Android 9 或更低版本 | 否 | (系统忽略) | 无访问权限 |
请注意,即使系统自动更新了您的应用对设备位置的访问权限后,用户也可以更改此访问级别。例如,用户可能会将您的应用的访问权限降低到仅前台访问,或完全撤销访问权限。在尝试访问设备位置之前,尤其是在前台服务中,您的应用应检查用户是否仍然允许您的应用接收此位置信息。
在 Android 10 设备上更新目标 API 级别时撤销访问权限
考虑一下这种情况:您的应用已安装在运行 Android 10 的设备上。如果您在此情况下将应用更新为以 Android 10 为目标,则设备会撤销 ACCESS_BACKGROUND_LOCATION
权限。
有关如何在应用处于后台时检索设备位置的更多信息,请参阅有关 接收定期位置更新 的指南。
从后台启动活动的限制
从 Android 10 开始,系统会对 从后台启动活动 施加限制。此行为更改有助于最大限度地减少对用户的干扰,并让用户更好地控制屏幕上显示的内容。只要您的应用是直接响应用户交互而启动活动的,则您的应用很可能不会受到这些限制的影响。
要了解有关从后台启动活动的推荐替代方法的更多信息,请参阅有关如何在应用中 提醒用户注意时间敏感事件 的指南。
标识符和数据
本节列出了与使用设备标识符和数据相关的特定更改。
移除联系人关联性
从 Android 10 开始,平台不再跟踪联系人关联性信息。因此,如果您的应用对用户的联系人进行搜索,则结果不会按交互频率排序。
关于 ContactsProvider
的指南包含一条说明,其中描述了从 Android 10 开始在所有设备上已 过时的字段和方法。
MAC 地址随机化
在运行 Android 10 或更高版本的设备上,系统默认情况下会传输随机化的 MAC 地址。
如果您的应用处理 企业用例,则平台会为与 MAC 地址相关的多个操作提供 API。
- 获取随机化的 MAC 地址: 设备所有者应用和配置文件所有者应用可以通过调用
getRandomizedMacAddress()
来检索分配给特定网络的随机化的 MAC 地址。 - 获取实际的出厂 MAC 地址: 设备所有者应用可以通过调用
getWifiMacAddress()
来检索设备的实际硬件 MAC 地址。此方法可用于跟踪设备群。
访问 /proc/net 文件系统的限制
在运行 Android 10 或更高版本的设备上,应用无法访问 /proc/net
(其中包含有关设备网络状态的信息)。需要访问此信息的应用(例如 VPN)应使用 NetworkStatsManager
或 ConnectivityManager
类。
对不可重置的设备标识符的限制
从 Android 10 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE
权限才能访问设备的不可重置标识符,其中包括 IMEI 和序列号。
受影响的方法包括:
Build
TelephonyManager
如果您的应用没有此权限,而您仍然尝试请求有关不可重置标识符的信息,则平台的响应会根据目标 SDK 版本而有所不同。
- 如果您的应用以 Android 10 或更高版本为目标,则会发生
SecurityException
。 - 如果您的应用以 Android 9(API 级别 28)或更低版本为目标,则如果应用具有
READ_PHONE_STATE
权限,则该方法将返回null
或占位符数据。否则,会发生SecurityException
。
许多用例不需要不可重置的设备标识符。例如,如果您的应用将不可重置的设备标识符用于广告追踪或用户分析目的,请改用 Android 广告 ID 来满足这些特定用例的需求。要了解详情,请参阅有关 唯一标识符最佳实践 的内容。
对剪贴板数据的访问权限有限
除非您的应用是默认的 输入法编辑器 (IME) 或当前具有焦点的应用,否则您的应用无法在 Android 10 或更高版本上访问剪贴板数据。
保护 USB 设备序列号
如果您的应用以 Android 10 或更高版本为目标,则在用户授予您的应用访问 USB 设备或附件的权限之前,您的应用无法读取序列号。
要了解有关使用 USB 设备的更多信息,请参阅有关如何 配置 USB 主机 的指南。
相机和连接性
本节列出了与相机元数据和连接性 API 相关的特定更改。
访问相机详细信息和元数据的限制
Android 10 更改了 getCameraCharacteristics()
方法默认返回的信息范围。特别是,您的应用必须具有 CAMERA
权限才能访问此方法返回值中包含的、可能特定于设备的元数据。
要了解有关这些更改的更多信息,请参阅有关 需要权限的相机字段 的部分。
启用和停用 Wi-Fi 的限制
以 Android 10 或更高版本为目标的应用无法启用或停用 Wi-Fi。WifiManager.setWifiEnabled()
方法始终返回 false
。
如果您需要提示用户启用和停用 Wi-Fi,请使用 设置面板。
对直接访问已配置的 Wi-Fi 网络的限制
为保护用户隐私,手动配置 Wi-Fi 网络列表仅限于系统应用和 设备策略控制器 (DPC)。给定的 DPC 可以是设备所有者或配置文件所有者。
如果您的应用以 Android 10 或更高版本为目标,并且它不是系统应用或 DPC,则以下方法不会返回有用的数据。
getConfiguredNetworks()
方法始终返回空列表。每个返回整数值的网络操作方法(
addNetwork()
和updateNetwork()
)始终返回 -1。每个返回布尔值的网络操作(
removeNetwork()
、reassociate()
、enableNetwork()
、disableNetwork()
、reconnect()
和disconnect()
)始终返回false
。
如果您的应用需要连接到 Wi-Fi 网络,请使用以下替代方法。
- 要触发与 Wi-Fi 网络的即时本地连接,请在标准
NetworkRequest
对象中使用WifiNetworkSpecifier
。 - 要添加 Wi-Fi 网络以供考虑向用户提供互联网访问,请使用
WifiNetworkSuggestion
对象。您可以通过调用addNetworkSuggestions()
和removeNetworkSuggestions()
分别添加和移除出现在自动连接网络选择对话框中的网络。这些方法不需要任何位置权限。
某些电话、蓝牙、Wi-Fi API 需要精确定位权限
如果您的应用以 Android 10 或更高版本为目标,则它必须具有 ACCESS_FINE_LOCATION
权限才能使用 Wi-Fi、Wi-Fi Aware 或蓝牙 API 中的多种方法。以下部分列出了受影响的类和方法。
电话
TelephonyManager
getCellLocation()
getAllCellInfo()
requestNetworkScan()
requestCellInfoUpdate()
getAvailableNetworks()
getServiceState()
TelephonyScanManager
requestNetworkScan()
TelephonyScanManager.NetworkScanCallback
onResults()
PhoneStateListener
onCellLocationChanged()
onCellInfoChanged()
onServiceStateChanged()
Wi-Fi
WifiManager
startScan()
getScanResults()
getConnectionInfo()
getConfiguredNetworks()
WifiAwareManager
WifiP2pManager
WifiRttManager
蓝牙
BluetoothAdapter
startDiscovery()
startLeScan()
BluetoothAdapter.LeScanCallback
BluetoothLeScanner
startScan()
权限
本节描述了 Android 权限模型的更新。
限制访问屏幕内容
为了保护用户的屏幕内容,Android 10 通过更改READ_FRAME_BUFFER
、CAPTURE_VIDEO_OUTPUT
和CAPTURE_SECURE_VIDEO_OUTPUT
权限的范围来防止对设备屏幕内容的静默访问。从 Android 10 开始,这些权限仅限于签名访问。
需要访问设备屏幕内容的应用应使用MediaProjection
API,该 API 会显示一个提示,要求用户提供同意。
面向用户的旧版应用权限检查
如果您的应用面向 Android 5.1(API 级别 22)或更低版本,则用户在运行 Android 10 或更高版本的设备上首次使用您的应用时会看到权限屏幕,如图 1 所示。此屏幕使用户有机会撤销系统先前在安装时授予您的应用的权限。
体感活动识别
Android 10 引入了android.permission.ACTIVITY_RECOGNITION
运行时权限,用于需要检测用户步数或对用户体感活动进行分类(例如步行、骑自行车或乘坐车辆)的应用。这旨在让用户了解如何在设置中使用设备传感器数据。
Google Play 服务中的一些库,例如活动识别 API和Google Fit API,除非用户已向您的应用授予此权限,否则不会提供结果。
设备上唯一需要声明此权限的内置传感器是计步器和步进检测器传感器。
如果您的应用面向 Android 9(API 级别 28)或更低版本,则如果您的应用满足以下所有条件,系统会根据需要自动向您的应用授予android.permission.ACTIVITY_RECOGNITION
权限
- 清单文件包含
com.google.android.gms.permission.ACTIVITY_RECOGNITION
权限。 - 清单文件不包含
android.permission.ACTIVITY_RECOGNITION
权限。
如果系统自动授予android.permission.ACTIVITY_RECOGNITION
权限,则在您更新应用以面向 Android 10 后,您的应用仍保留该权限。但是,用户可以随时在系统设置中撤销此权限。
从 UI 中删除的权限组
从 Android 10 开始,应用无法在 UI 中查找权限是如何分组的。