安卓 11 重磅上线,快来看看,是不是熟悉的配方,大专生面试阿里 P7 居然过了
数据迁移到使用分区存储时可见的目录:
在以 Android 11 为目标平台之前,应将数据迁移到与分区存储兼容的目录。在大多数情况下,可以将数据迁移到应用的应用专用目录。
如果有要迁移的数据,当用户升级到以 Android 11 为目标平台的新版应用时,可以保留旧版存储模型。这样,用户就可以保留对应用之前用来保存数据的目录中存储的应用数据的访问权限。要启用旧版存储模型以进行升级,请在应用的清单中将 preserveLegacyExternalStorage
属性设为 true
。
这里需要注意以下两点:
大多数应用都不需要使用
preserveLegacyExternalStorage
。此标记仅适用于这样一种情况:你将应用数据迁移到了与分区存储兼容的位置,并且希望用户在更新你应用时保留对数据的访问权限。使用此标记会导致更难以测试分区存储对应用的用户有何影响,因为当用户更新应用时,它会继续使用旧版存储模型。如果使用
preserveLegacyExternalStorage
,则旧版存储模型只在用户卸载应用之前保持有效。如果用户在搭载 Android 11 的设备上安装或重新安装应用,则无论preserveLegacyExternalStorage
的值是什么,应用都无法停用分区存储模型。
测试分区存储
如果要在应用中启用分区存储,而不考虑应用的目标 SDK 版本和清单标记值,请启用以下应用兼容性标记:
DEFAULT_SCOPED_STORAGE
(默认情况下,对所有应用处于启用状态)FORCE_ENABLE_SCOPED_STORAGE
(默认情况下,对所有应用处于停用状态)
要停用分区存储而改用旧版存储模型,请取消设置这两个标记。
管理设备存储空间
如果你的应用是文件管理器应用并且在 Android 11 上运行,它就不能再删除其他应用的缓存文件,即使您的应用具有所有文件访问权限也是如此(清理文件的应用尤其需要注意,比如某某管家、卫士啥的)。相反,你应执行以下操作:
通过调用
ACTION_MANAGE_STORAGE
intent 操作来检查可用空间。如果设备上的可用空间不足,请提示用户同意让您的应用清除所有缓存。为此,请调用
ACTION_CLEAR_APP_CACHE
intent 操作。
这里需要注意:ACTION_CLEAR_APP_CACHE
intent 操作会严重影响设备的电池续航时间,并且可能会从设备上移除大量的文件。
媒体文件访问权限
这个很赞,Android 11 增加了以下访问媒体功能。
执行批量操作
为实现各种设备之间的一致性并增加用户便利性,Android 11 向 MediaStore
API 中添加了多种方法。对于希望简化特定媒体文件更改流程(例如在原位置编辑照片)的应用而言,这些方法尤为有用。
添加的方法如下:
[
createWriteRequest()
](developer.android.google.cn/reference/a…(android.content.ContentResolver, java.util.Collection))
用户向应用授予对指定媒体文件组的写入访问权限的请求。
[
createFavoriteRequest()
](developer.android.google.cn/reference/a…(android.content.ContentResolver, java.util.Collection, boolean))
用户将设备上指定的媒体文件标记为“收藏”的请求。对该文件具有读取访问权限的任何应用都可以看到用户已将该文件标记为“收藏”。
[
createTrashRequest()
](developer.android.google.cn/reference/a…(android.content.ContentResolver, java.util.Collection, boolean))
用户将指定的媒体文件放入设备垃圾箱的请求。垃圾箱中的内容在特定时间段(默认为 7 天)后会永久删除。
[
createDeleteRequest()
](developer.android.google.cn/reference/a…(android.content.ContentResolver, java.util.Collection))
用户立即永久删除指定的媒体文件(而不是先将其放入垃圾箱)的请求。
系统在调用以上任何一个方法后,会构建一个 PendingIntent
对象。应用调用此 intent 后,用户会看到一个对话框,请求用户同意应用更新或删除指定的媒体文件。
使用原始路径访问文件
从 Android 11 开始,具有 READ_EXTERNAL_STORAGE
权限的应用可以使用直接文件路径和原生库来读取设备的媒体文件。通过这项新功能,应用可以更顺畅地使用第三方媒体库。
文件和目录访问限制
以下与存储访问框架 (SAF) 相关的变更只有在应用以 Android 11 为目标平台时才会生效。
访问目录
无法再使用 ACTION_OPEN_DOCUMENT_TREE
intent 操作来请求访问以下目录:
Downloads
根目录。设备制造商认为可靠的各个 SD 卡卷的根目录,无论该卡是模拟卡还是可移除的卡。
访问文件
无法再使用 ACTION_OPEN_DOCUMENT_TREE
或 ACTION_OPEN_DOCUMENT
intent 操作来请求用户从以下目录中选择单独的文件:
Android/data/
目录及其所有子目录。Android/obb/
目录及其所有子目录。
权限
不管应用的目标 SDK 版本是什么,以下变更均会在 Android 11 中生效:
存储运行时权限已重命名为文件和媒体。
如果应用未停用分区存储并且请求
READ_EXTERNAL_STORAGE
权限,则用户会看到不同于 Android 10 的对话框。该对话框会指示应用正在请求访问照片、视频、音频剪辑和文件。用户可以在系统设置中查看哪些应用具有
READ_EXTERNAL_STORAGE
权限。在设置 > 隐私 > 权限管理器 > 文件和媒体页面上,具有该权限的每个应用都列在允许存储所有文件下。
这里要注意:如果应用以 Android 11 为目标平台,切记,对“所有文件”的这种访问权限是只读访问权限。要使用此应用读取和写入共享的存储空间中的所有文件,需要具有所有文件访问权限。
所有文件访问权限
某些应用的核心用例需要访问大量的文件,如文件管理操作或备份和恢复操作。这些应用可通过执行以下操作来获取“所有文件访问权限”:
声明
MANAGE_EXTERNAL_STORAGE
权限。使用
ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
intent 操作将用户引导至一个系统设置页面,在该页面上,用户可以为应用启用以下选项:授予所有文件的管理权限。
“所有文件访问权限”可授予以下权限:
对共享的存储空间内所有文件的读写访问权限。
对
MediaStore.Files
表的内容的访问权限。
应用可以使用 MediaStore
API 或原始文件路径来访问这些文件。如果应用使用存储访问框架,不能使用它来访问“所有文件访问权限”提供的其他文件和目录。获得此权限的应用仍然无法访问属于其他应用的应用专用目录。这些目录在存储卷上显示为 Android/data/
的子目录。
自定义消息框视图被屏蔽
出于安全方面的考虑,同时也为了保持良好的用户体验,如果包含自定义视图的消息框是以 Android 11 为目标平台的应用从后台发送的,则系统会屏蔽这些消息框。请注意,仍允许使用文本消息框;此类消息框是使用 Toast.makeText()
创建的,并不调用 setView()
。
如果您的应用仍尝试从后台发布包含自定义视图的消息框,则系统不会向用户显示相应的消息,而会执行以下操作:
显示以下消息框消息:
Background custom toast blocked for package package-name. See g.co/dev/toast.
在 logcat 中记录以下消息:
W/NotificationService: Blocking custom toast from package due to package not in the foreground
如果希望在消息框(文本消息框或自定义消息框)出现或消失时收到通知,请使用新的 addCallback()
) 方法。
这里需要注意,由于平台行为发生了变更,以 Android 11 为目标平台的应用会发现文本消息框受到以下负面影响:
getView()
方法返回null
。以下方法的返回值并不反映实际值,因此尽量别使用:
以下方法是空操作,因此应用不应使用:
[
setMargin()
](developer.android.google.cn/reference/a…(float, float))[
setGravity()
](developer.android.google.cn/reference/a…(int, int, int))
前台服务类型
从 Android 9 开始,应用仅限于在前台访问摄像头和麦克风。为了进一步保护用户,Android 11 更改了前台服务访问摄像头和麦克风相关数据的方式。如果应用以 Android 11 为目标平台并且在某项前台服务中访问这些类型的数据,则需要在该前台服务的声明的 foregroundServiceType
属性中添加新的 camera
和 microphone
类型。
来举个例子吧,如果应用中的某项前台服务需要访问与设备的位置信息和摄像头相关的数据,请按以下代码段所示声明该服务:
<manifest>...<service ... android:foregroundServiceType="location|camera" /></manifest>复制代码
MAC 地址
在以 Android 10(API 级别 29)及更低版本为目标平台的应用中,MAC 地址的随机分配是基于每个 SSID 进行的,因为 Passpoint 可以连接到同一资料的不同 SSID。而在以 Android 11(API 级别“R”)及更高版本为目标平台的应用中,Passpoint 网络的 MAC 地址随机分配将更改为针对每个完全限定域名 (FQDN) 进行分配。
对于以 API 级别“R”及更高级别为目标平台的应用,非特权应用将无法访问设备的 MAC 地址;只有具有 IPv4 地址的网络接口可见。会影响 getifaddrs()
和 NetworkInterface.getHardwareAddress()
) 方法,以及 RTM_GETLINK
netlink 消息的发送。
下面列出了此变更会以哪些方式来影响应用:
NetworkInterface.getHardwareAddress()
会针对每个接口返回 null。应用无法对
NETLINK_ROUTE
套接字使用bind()
函数。IP
命令不会返回有关接口的信息。
这些变更强制执行不要使用 MAC 地址中提供的指导。
请注意,大多数开发者应使用级别较高的 ConnectivityManager
API 而不是级别较低的 NetworkInterface
/getifaddrs()
API。
每个进程的网络访问控制
从 Android 11 开始,处理敏感用户数据的应用可以向每个进程授予网络访问权限。通过明确指定允许哪些进程访问网络,您可以隔离不需要上传数据的所有代码。
虽然不能保证防止应用意外上传数据,但该功能可让降低应用中的错误导致数据泄露的几率。
下面显示了使用这项新功能的清单文件的示例:
<processes><process /><deny-permission android:name="android.permission.INTERNET" /><process android:process=":withoutnet1" /><process android:process="com.android.cts.useprocess.withnet1"><allow-permission android:name="android.permission.INTERNET" /></process><allow-permission android:name="android.permission.INTERNET" /><process android:process=":withoutnet2"><deny-permission android:name="android.permission.INTERNET" /></process><process android:process="com.android.cts.useprocess.withnet2" /></processes>复制代码
一次性权限
在 Android 11 中,每当应用请求与位置信息、麦克风或摄像头相关的权限时,应用都会获得临时的一次性权
限。这个其实在苹果中也有类似的权限申请。
评论