Android Q Beta 变化与特点 隐私和位置
Android Q隐私清单
最隐私的变化
范围存储
对共享外部存储中文件访问的新限制。使用特定于应用程序的目录或强类型媒体集合中的文件完成大部分工作。
存储在路径中的文件/sdcard
,Android Q继续使用 READ_EXTERNAL_STORAGE
和 WRITE_EXTERNAL_STORAGE
权限(运行时)
针对Android Q的应用(以及选择更改的应用)会获得外部存储的过滤视图,此类应用程序只能查看其特定于应用程序的目录和特定类型的媒体,因此应用程序无需请求任何其他用户权限
过滤视图到外部存储
默认情况下,如果你的应用程序以Android Q为目标,它会对外部存储设备上的文件进行过滤。应用程序可以使用Context.getExternalFilesDir()在特定于应用程序的目录下存储自己需要的文件
具有过滤视图的应用程序始终具有对其创建的文件的读/写访问权,无论是在特定于应用程序的目录内还是目录外。您的应用程序不需要声明任何存储权限来访问这些文件
您的应用程序可以访问其他应用程序创建的文件,只有在以下两个条件都为真:
1.您的应用程序已被授予READ_EXTERNAL_STORAGE权限。
2.文件驻留在以下定义良好的媒体集合中:
-
Photos, 存储在
MediaStore.Images
中。 -
Videos, 存储在
MediaStore.Video
中. -
Music files, 存储在
MediaStore.Audio
中.**Warning:**在2020年的主要平台版本中,所有应用程序都将需要范围存储,这与目标SDK级别无关。因此,您应该确保您的应用程序能够很好地提前使用范围存储。为此,请确保在运行应用程序的Android Q设备上启用了该行为
选择退出过滤视图
在应用程序完全兼容或测试之前,可以根据应用程序的目标SDK级别或名为requestLegacyExternalStorage的新清单属性临时选择不使用范围存储行为
- 目标Android 9 (API级别28)或更低。
- 如果你的目标是Android Q,在你的应用程序清单文件中将requestLegacyExternalStorage的值设置为true
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
要测试针对Android 9或更低版本的应用程序如何使用范围存储,可以通过将requestLegacyExternalStorage的值设置为false来选择行为
筛选视图文件访问的摘要
下表总结了一个应用程序如何将过滤后的视图保存到外部存储中来访问文件:
文件位置 | 需要权限 | 访问方法(*) | 卸载应用程序时删除的文件? |
---|---|---|---|
应用专用目录 | 没有 | getExternalFilesDir() | 是 |
媒体收藏 (照片,视频,音频)Media collections (photos, videos, audio) | READ_EXTERNAL_STORAGE 仅在 访问其他应用程序的文件时 | MediaStore | 没有 |
下载 (文件和 电子书(Downloads(documents and e-books)) | 没有 | 存储访问框架 (加载系统的文件选择器) | 没有 |
更多参考:https://developer.android.google.cn/preview/privacy/scoped-storage
限制后台活动启动
从Android Q Beta 4开始,此更改具有以下属性:
- 如果在没有用户交互的情况下启动活动,则会影响您的应用
- 通过使用通知触发的活动进行缓解
- 通过启用“ 允许后台活动启动开发人员”选项禁用限制
允许活动启动的条件
只有满足以下一个或多个条件时,在Android Q上运行的应用才能启动活动:
-
该应用程序具有可见窗口,例如前台中的一个活动。
注意:出于活动启动的目的,前台服务不会 将应用程序限定为位于前台。
-
该应用程序在前台任务的后台堆栈中有一个活动。
-
该应用程序最近启动了一个活动。
-
该应用程序调了
finish()
在一个最近活动。仅当应用程序在前台有活动或者当前任务的后台堆栈中的活动finish()
被调用时才适用。 -
该应用程序具有受系统约束的服务。这种情况仅适用于下列服务,可能需要启动UI: ,
AccessibilityService
,AutofillService
,CallRedirectionService
,HostApduService
,InCallService
,TileService
,VoiceInteractionService
和VrListenerService
。 -
该应用程序有一个由另一个可见的应用程序绑定的服务。请注意,绑定到该服务的应用程序必须保持可见,以便该应用程序在后台成功启动活动。
-
该应用程序
PendingIntent
从系统收到通知 。对于服务和广播接收器的待处理意图,应用程序可以在发送待处理意图后的几秒钟内启动活动。 -
该应用会收到一个
PendingIntent
从不同的可见的应用发送的。 -
应用程序接收一个系统广播,该应用程序将在其中启动一个UI。示例包括ACTION_NEW_OUTGOING_CALL和SECRET_CODE_ACTION。在广播发送后,该应用程序几秒钟后可以启动活动。
-
该应用程序通过
CompanionDeviceManager
API 与配套硬件设备相关联 。此API允许应用程序启动活动以响应用户在配对设备上执行的操作。 -
该应用已被
SYSTEM_ALERT_WINDOW
用户授予 许可
为时间敏感的事件创建通知
几乎在所有情况下,后台应用程序都应该创建通知来向用户提供信息,而不是直接启动某个活动。
在特定情况下,您的应用程序可能需要紧急获得用户的注意,例如正在进行的警报或来电。您可能已经将应用程序配置为此目的启动后台活动。要在运行Android Q的设备上提供相同的行为,请参考:建立通知
https://developer.android.google.cn/preview/privacy/background-activity-starts
向用户显示通知
在向用户显示通知时,用户可以根据当前上下文选择是否确认或取消应用程序的警告或提醒。例如,用户可以选择接受或拒绝来电。
如果您的通知是一个正在进行的通知,例如一个传入的电话呼叫,请将该通知与前台服务关联。下面的代码片段显示了如何显示与前台服务关联的通知:
//为每个通知的“notificationId”提供一个惟一的整数。
startForeground (notificationId,notification)
注意:当用户使用设备时,系统UI可能会选择显示警告通知,而不是启动全屏意图
禁用行为更改
建议启用此行为更改。这样,当Android Q安装在用户的设备上时,你就可以更加自信地让用户继续与你的应用程序进行交互。
但是,如果此更改阻止您在应用程序中测试核心工作流,则可以通过完成以下任务之一禁用测试期间的行为更改:
导航到“设置>开发人员选项”,并启用“允许后台活动启动”选项。
在终端窗口中运行以下命令:
adb shell settings put global background_activity_starts_enabled 1
应用程序访问设备位置
从Android Q Beta 4开始,此更改具有以下属性:
- 如果您在后台请求访问设备位置,则会影响您的应用
- 在后台授予应用访问设备位置后,用户可能会收到提醒
- 通过使用新权限在后台访问位置,并在没有后台位置更新的情况下确保优雅降级,来进行缓解这种情况
- Android Q上始终启用行为
Android Q让用户可以更多地控制应用程序何时可以访问设备位置。当运行在Android Q上的应用程序请求位置访问时,用户可以看到如图1所示的对话框。此对话框允许用户将位置访问权限授予两个不同的区段:在使用应用程序(仅在前台)或一直使用(前台和后台)时
为了支持用户对应用程序访问位置信息的额外控制,Android Q引入了一个新的位置权限ACCESS_BACKGROUND_LOCATION。与现有的ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION权限不同,新权限只影响应用程序在后台运行时对位置的访问。一个应用程序被认为是在后台,除非它的某个活动是可见的,或者该应用程序正在运行一个前台服务
请求后台位置
如果你的应用以Android Q为目标,需要在后台运行时访问设备位置,你必须在应用的manifest文件中声明新的权限:
<manifest>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>
如果您的应用程序运行在Android Q上,但目标是Android 9 (API级别28)或更低,则适用以下行为:
如果您的应用程序为ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION声明了一个元素,系统会在安装期间自动为ACCESS_BACKGROUND_LOCATION添加一个元素。
如果应用程序请求ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION,系统会自动将ACCESS_BACKGROUND_LOCATION添加到请求中。
**注意:**虽然您的应用程序可以请求和接收ACCESS_BACKGROUND_LOCATION权限,但是用户可以通过选择您的应用程序应该只访问前台的位置信息来撤销该权限。
请求后台位置访问
如果您的应用程序的用例需要在后台运行时访问位置信息,请务必考虑您需要此访问权限的程度:
- 您的应用程序的用例依赖于用户启动的操作的继续,例如导航或智能家庭操作。在这种情况下,配置您的前台服务,以便在用户按下其设备上的“ **主页”**按钮或关闭其设备显示后,即使用户已请求您的应用只能访问设备位置在前台。
- 您应用的用例依赖于定期检查设备的位置,例如地理围栏或位置共享。在这种情况下,您的应用应向用户说明他们需要始终让您的应用访问设备位置才能正常运行,然后请求访问后台位置
用户发起的操作延续
**注意:**如果您的应用在后台运行时不需要访问位置,则最佳做法是定位Android Q而不是请求新的后台位置权限。这样,您的应用只会在用户使用该应用时收到位置更新。
这种应用程序的一个示例出现在GitHub上的 LocationUpdatesForegroundService项目中
在用户只允许应用程序前台访问位置的情况下,即使用户按下了设备上的Home按钮或关闭了设备的显示,用户仍然可能启动一个工作流,要求应用程序访问他们的位置
要在这个特定的用例中保留对设备位置的访问,启动一个前台服务,你需要在你的应用程序清单中声明了类型为“location”一个前台服务:
<service
android:name="MyNavigationService"
android:foregroundServiceType="location" ... >
...
</service>
在启动前台服务之前,请确保您的应用程序仍然可以访问设备的位置:
boolean permissionAccessCoarseLocationApproved =
ActivityCompat.checkSelfPermission(this,
permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED;
if (permissionAccessCoarseLocationApproved) {
// App has permission to access location in the foreground. Start your
// foreground service that has a foreground service type of "location".
} else {
// Make a request for foreground-only location access.
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.ACCESS_COARSE_LOCATION},
your-permission-request-code);
}
定期检查设备的位置
您的应用程序可能有一个用例,要求始终访问设备的位置。这些用例包括与朋友和家人的地理会议和位置共享。
如果这些条件适用于您的应用程序,您可以继续请求位置更新而不做任何更改,只要用户允许您的应用程序随时访问设备的位置
警告:用户可以选择同时拒绝访问设备的位置,并阻止您的应用程序在将来请求访问设备的位置。你的应用程序应该处理这个“拒绝,不要再问”用例
下面的代码片段演示了如何声明一个随时请求访问设备位置的服务:
<!-- It's unnecessary to include a foreground service type for services that must have
access to the device's location "all the time" in order to run successfully.-->
<service
android:name="MyFamilyLocationSharingService" ... >
...
</service>
此类应用程序的一个例子是GitHub上的LocationUpdatesPendingIntent项目。
每次用户选择允许您的应用程序全天候访问设备位置时,系统都会安排一个通知发送给用户。这个通知提醒用户,他们已经允许您的应用程序一直访问设备位置
虽然您的应用程序可以请求访问后台的位置,但用户可以选择只减少应用程序对前台的访问或完全取消访问。因此,无论什么时候您的应用程序启动一个服务,都要检查用户是否仍然允许您的应用程序访问后台的位置信息
如果用户要求您的应用程序只访问前台的位置,那么最好的做法是让应用程序显示一个自定义对话框,提醒用户如果没有始终访问其位置,应用程序中的工作流将无法正常工作。用户确认此对话框后,可以请求后台位置
为设备升级场景设计
设备升级到Android Q后,位置权限状态的变化
NOTE:即使系统自动更新了您的应用程序对设备位置的访问权限,用户也可以选择更改此访问级别。用户可能只减少应用程序对前台的访问,或者完全取消访问。
因此,在访问设备的位置更新之前,请遵循最佳实践,检查用户是否仍然允许您的应用程序接收该位置信息
发现位置最佳实践
- 仅仅询问您需要的权限
除非绝对必要,否则不要在应用程序启动时请求位置权限。
如果您的应用程序针对Android Q,并且只在前台运行时需要访问位置信息,那么不要请求ACCESS_BACKGROUND_LOCATION。
- 如果没有获得许可,则支持优雅的降级
为了保持良好的用户体验,设计你的应用程序,使它可以优雅地处理以下情况:
你的应用程序不能访问任何位置信息。
您的应用程序在后台运行时无法访问位置信息。
附加资源
有关应用程序访问设备位置的更改的更多信息,请参阅以下附加资源:
- LocationUpdatesPendingIntent: 一个应用程序,要求一直(all-the-time)访问设备位置
- LocationUpdatesForegroundService: 一个应用程序,它声明一个类型为“location”的前台服务,并且只在使用该应用程序时请求访问设备位置.
数据和标识符的更改
影响所有应用的变化
联系人亲和力
从Android Q开始,该平台不再跟踪联系人亲缘关系信息。因此,如果您的应用对用户的联系人进行搜索,则结果不再按交互频率排序。
“联系人提供程序”指南包含一个通知,说明自 Android Q起所有设备上已废弃的特定字段和方法。
随机MAC地址
在Android Q上运行的设备默认传输随机MAC地址。如果您的应用处理企业用例,该平台会提供几个新的API:
- **获取随机MAC地址:**设备所有者应用和配置文件所有者应用可以通过调用检索分配给特定网络的随机MAC地址
getRandomizedMacAddress()
。 - **获取实际的工厂MAC地址:**设备所有者应用程序可以通过调用来检索设备的实际硬件MAC地址
getWifiMacAddress()
。此方法对于跟踪设备队列非常有
访问/ proc / net文件系统
Android Q删除对其的访问权限/proc/net
,其中包括有关设备网络状态的信息。需要访问此信息的应用程序(如VPN)应引用 NetworkStatsManager
和 ConnectivityManager
类。
不可重置的设备标识符
从Android Q开始,应用必须具有READ_PRIVILEGED_PHONE_STATE
特权权限才能访问设备的不可重置标识符,包括IMEI和序列号。许多用例不需要不可重置的设备标识符。如果您的应用程序没有权限,并且您尝试询问有关标识符的信息,则平台的响应会因目标SDK版本而异:
- 如果您的应用针对Android Q,
SecurityException
则会出现问题。 - 如果您的应用针对Android 9(API级别28)或更低版本,则该方法会返回
null
或占位符数据(如果该应用具有该READ_PHONE_STATE
权限)。否则,SecurityException
发生了
**注意:**如果您的应用是设备或个人资料所有者应用,则您只需拥有READ_PHONE_STATE
访问不可重置设备标识符的 权限,即使您的应用针对Android Q.此外,如果您的应用具有特殊的运营商权限,则您不需要任何访问标识符的权限
如果您的应用使用不可重置的设备标识符进行广告跟踪或用户分析,请 为这些特定用例创建Android广告ID。要了解更多信息,请参阅
唯一标识符最佳做法:https://developer.android.google.cn/training/articles/user-data-ids
访问剪贴板数据
除非您的应用程序是默认输入法编辑器(IME)或当前具有焦点的应用程序,否则您的应用程序无法访问剪贴板数据
影响针对Android Q的应用的更改
访问USB串行需要用户许可
如果您的应用针对Android Q,则您的应用只能在用户授予您访问USB设备或配件的应用权限后才能读取序列号
更改相机和连接
影响所有应用的变化
访问所有相机信息需要获得许可
Android Q会更改getCameraCharacteristics()
默认情况下该方法返回的信息范围 。特别是,您的应用必须具有CAMERA
权限才能访问此方法的返回值中包含的潜在特定于设备的元数据
影响针对Android Q的应用的更改
启用和禁用Wi-Fi的限制
针对Android Q的应用无法启用或停用Wi-Fi。该 WifiManager.setWifiEnabled()
方法总是返回false
。
如果需要,请使用设置面板提示用户启用和禁用Wi-Fi
Wi-Fi网络配置限制
为了保护用户隐私,现在将Wi-Fi网络列表的手动配置限制在系统应用和 设备策略控制器(DPC)中。给定的DPC可以是设备所有者或配置文件所有者。
如果您的应用不符合其中一个类别且定位到Android Q,则以下方法不再返回有用数据:
- 该
getConfiguredNetworks()
方法始终返回一个空列表。 - 返回一个整数值-每个网络操作方法
addNetwork()
和updateNetwork()
-always返回-1。 - 每个网络操作,返回一个布尔值- ,
removeNetwork()
,reassociate()
,enableNetwork()
,disableNetwork()
,reconnect()
和disconnect()
-always回报false
。
**注意:**如果运营商应用程序呼叫getConfiguredNetworks()
,系统将返回仅包含运营商配置的网络的列表。
如果您的应用需要连接到Wi-Fi网络,请使用以下备用方法:
- 要触发与Wi-Fi网络的即时本地连接,请使用
WifiNetworkSpecifier
标准NetworkRequest
对象。 - 要添加Wi-Fi网络以考虑为用户提供Internet访问,请使用
WifiNetworkSuggestion
对象。您可以分别通过调用addNetworkSuggestions()
和 添加和删除出现在自动连接网络选择对话框中的网络removeNetworkSuggestions()
。这些方法不需要任何位置权限
电话,Wi-Fi,蓝牙API所需的精确位置许可
除非您的应用具有此ACCESS_FINE_LOCATION
权限,否则 在Android Q上运行时,您的应用无法在Wi-Fi,Wi-Fi Aware或蓝牙API中使用多种方法。以下列表显示了受影响的方法。
**注意:**如果您的应用在Android Q上运行但针对的是Android 9(API级别28)或更低级别,则只要您的应用具有ACCESS_COARSE_LOCATION
或 拥有该ACCESS_FINE_LOCATION
权限,您就可以使用受影响的API
电话
TelephonyManager
getCellLocation()
getAllCellInfo()
requestNetworkScan()
requestCellInfoUpdate()
getAvailableNetworks()
getServiceStateForSubscriber
getServiceState()
TelephonyScanManager
requestNetworkScan()
TelephonyScanManager.NetworkScanCallback
onResults()
PhoneStateListener
onCellLocationChanged()
onCellInfoChanged()
onServiceStateChanged()
无线上网
WifiManager
startScan()
getScanResults()
getConnectionInfo()
getConfiguredNetworks()
WifiAwareManager
WifiP2pManager
WifiRttManager
蓝牙
BluetoothAdapter
startDiscovery()
startLeScan()
LeScanCallback()
权限更改
以下更改会影响在Android Q上运行的所有应用,即使它们定位到Android 9(API级别28)或更低级别
限制访问屏幕内容
为了保护用户的屏幕内容,Android Q的防止了对设备的屏幕内容无声接入改变的范围READ_FRAME_BUFFER
,CAPTURE_VIDEO_OUTPUT
和CAPTURE_SECURE_VIDEO_OUTPUT
权限,使他们 签名访问 而已。
需要访问设备屏幕内容的应用应使用 MediaProjection
API,该API会显示提示,要求用户提供同意。
面向用户的权限检查旧应用程序
如果您的应用针对Android 5.1(API级别22)或更低版本,则用户首次在Android Q上运行您的应用时会看到权限屏幕,如图1所示。这个屏幕让用户有机会撤销系统在安装时授予应用程序的权限。
**警告:**如果您要在Google Play上发布应用,则必须定位到Android 8.0(API级别26)或更高版本。要了解详情,请参阅有关如何满足Google Play目标API级别要求的指南
身体活动识别
Android Q ACTIVITY_RECOGNITION
为需要检测用户步数或对用户的身体活动进行分类的应用程序引入了新的 运行时权限,例如步行,骑自行车或在车辆中移动。这旨在让用户了解设置中如何使用设备传感器数据。
如果您的应用依赖于设备上其他内置传感器的数据,例如加速度计和陀螺仪,则无需在应用中声明此新权限。
如果您的应用针对Android 9(API级别28)或更低版本并com.google.android.gms.permission.ACTIVITY_RECOGNITION
在其清单文件中指定 权限,则系统会根据需要自动向您的应用授予此权限。当您将应用更新为定位Android Q时,该平台旨在保留该权限; 但是,由于已知的平台问题,在更新时会重置权限。此外,用户可以随时在系统设置中撤消此权限。
**注意:**除非用户已授予您的应用此权限,否则Google Play服务中的某些库(例如活动识别API)不会提供结果
从UI中删除权限组
在Android Q中,应用程序无法查看权限在UI中是如何分组的