android协程作用域
Scoped storage is the newly introduced storage system by Android. But before diving into scoped storage, let us first discuss what shared storage is and its requirements in Android.
范围存储是Android最新推出的存储系统。 但是在深入研究作用域存储之前,让我们首先讨论什么是共享存储及其在Android中的要求。
当前场景 (Current Scenario)
- All apps have their own private directory in internal storage, i.e Android/data/your package name, not visible to other apps. 所有应用程序在内部存储中都有自己的私有目录,即Android /数据/您的程序包名称,其他应用程序不可见。
- Most of the current apps require broad storage permissions to perform simple functions. For example, downloading an image or as an image picker, etc. At the time of uninstalling the app, most of the time, files don’t get deleted. This results in insufficient storage. 当前大多数应用程序都需要广泛的存储权限才能执行简单的功能。 例如,下载图像或作为图像选择器等。在卸载应用程序时,大多数情况下,文件不会被删除。 这导致存储空间不足。
Android 10 comes up with a solution: scoped storage.
Android 10提供了一个解决方案:范围存储。
什么是范围存储? (What Is Scoped Storage?)
It’s a concept of storing files, images, etc. separately, called Collections, which restrict the conventional access of the whole storage.
这是单独存储文件,图像等的概念,称为Collections ,它限制了整个存储的常规访问。
- Better attribution: This means that the system knows which app created which file. It is useful when the app is uninstalled, so all the data related to the app is also uninstalled. 更好的归因:这意味着系统知道哪个应用创建了哪个文件。 卸载应用程序时,此功能很有用,因此与该应用程序相关的所有数据也将被卸载。
- Protecting app data: Internal app directories and external app directories are private. 保护应用程序数据:内部应用程序目录和外部应用程序目录是私有的。
- Protect user data: The downloaded image cannot be used by another app. 保护用户数据:下载的图像不能被其他应用使用。
主要特点 (Key Features)
- Unrestricted access to its individual app storage (internal/external): No permission required. 不受限制地访问其单个应用程序存储(内部/外部):无需权限。
- Unrestricted access to media files and download collections: E.g. Save the image file without permission. 不受限制地访问媒体文件和下载收藏集:例如,未经许可保存图像文件。
- Only media collections can be read with storage permissions. 具有存储权限的只能读取媒体集合。
Location metadata
ACCESS_MEDIA_LOCATION
for the location of the image.图像位置的位置元数据
ACCESS_MEDIA_LOCATION
。For files like PDFs, text, etc. use System Picker.
对于PDF,文本等文件,请使用System Picker 。
- Reading and writing outside of a collection requires the “System Picker”. 在集合外进行读写需要使用“系统选择器”。
我们如何实施它? (How Do We Implement It?)
Use
ACTION_OPEN_DOCUMENT
to select a file.用
ACTION_OPEN_DOCUMENT
选择一个文件。
Use
ACTION_OPEN_DOCUMENT_TREE
to select a folder: This will ask for permission in Android 10, for full access to that folder.用
ACTION_OPEN_DOCUMENT_TREE
选择一个文件夹: 这将要求Android 10中的权限,以获取对该文件夹的完全访问权限。
- Content access using raw file paths. 使用原始文件路径的内容访问。
Save image file using the MediaStore API.
使用MediaStore API保存图像文件。
在MediaStore中使用IS_PENDING标志的目的 (The purpose of using the IS_PENDING flag in MediaStore)
MediaStoreDemo.kt MediaStoreDemo.ktWhen you insert an item that is marked as pending intent (value 1), by default, it will be hidden from other apps on the device.
默认情况下,当您插入标记为待定意图的项目(值1)时,该项目将对设备上的其他应用程序隐藏。
This can be used when you use long-running downloads like video downloading from a URL. Once the download is completed, set the pending intent to 0 to reveal it to other apps to the device.
当您使用长期下载(例如从URL下载视频)时,可以使用此功能。 下载完成后,将待处理的意图设置为0,以将其显示给设备的其他应用程序。
- In the above example, we have not set/specified the path to store the image, so the OS automatically chooses the path based on the file type. Here, we took the image/JPEG, so it will store the image to the pictures folder by default. 在上面的示例中,我们尚未设置/指定存储图像的路径,因此OS将根据文件类型自动选择路径。 在这里,我们拍摄了图像/ JPEG,因此默认情况下会将图像存储到图片文件夹。
You can also choose the file path with
Media.RELATIVE_PATH.
您也可以使用
Media.RELATIVE_PATH .
选择文件路径Media.RELATIVE_PATH .
VOLUME_EXTERNAL_PRIMARY
to store in primary storage. And to get list of storages available on the phone useMediaStore.getExternalVolumeNames(context)
.VOLUME_EXTERNAL_PRIMARY
存储在主存储器中。 要获取电话上可用的存储列表,请使用MediaStore.getExternalVolumeNames(context)
。
Upon getting a document URI returned, we can use it.
[ContentResolver.takePersistableUriPermission]
to persist the permission across restarts.收到文档URI后,我们可以使用它。
[ ContentResolver.takePersistableUriPermission ]
可以在重新启动之间持久保留权限。If your app uses scoped storage, raw file path access is limited to the app-specific directories in external storage, even if your app has been granted the
READ_EXTERNAL_STORAGE
permission. If your app attempts to use a raw path to open a file within external storage that doesn’t reside in the app-specific directory, aFileNotFoundException
occurs. For example, the path for a file outside the app-specific directory is/sdcard/DCIM/ABC.JPG
. Instead, your app should use methods in the MediaStore API.如果您的应用使用范围存储,则原始文件路径访问仅限于外部存储中特定于应用的目录,即使您的应用已被授予
READ_EXTERNAL_STORAGE
允许。 如果您的应用尝试使用原始路径打开不在应用特定目录中的外部存储中的文件,则FileNotFoundException
发生。 例如,特定于应用程序的目录之外的文件的路径是/sdcard/DCIM/ABC.JPG
。 相反,您的应用应使用MediaStore API中的方法。In Android Q and above, it isn’t possible to modify or delete items in MediaStore directly, and explicit permission must usually be obtained to do this. The way it works is that the OS will throw a
RecoverableSecurityException
, which we can catch here. Inside, there’s anIntentSender
which the activity can use to prompt the user to grant permission to the item so it can be either updated or deleted.在Android Q及更高版本中,无法直接修改或删除MediaStore中的项目,通常必须获得显式许可才能执行此操作。 它的工作方式是操作系统将抛出
RecoverableSecurityException
,我们可以在这里捕获它。 内部有一个IntentSender
,活动可以使用该IntentSender
来提示用户授予该项目的权限,以便可以对其进行更新或删除。
RequestLegacyAccess标签 (RequestLegacyAccess tag)
In the Manifest
file, we can still add that we want to use the permission access like in lower versions than Android 10. But it is only used by 2% of Android apps, and it is also going to be deprecated in the next version of Android.
在Manifest
文件中,我们仍然可以添加想要使用权限访问的功能,例如在低于Android 10的较低版本中使用。但是,只有2%的Android应用程序使用该权限访问权限,并且在下一版本的Android应用程序中也会弃用该权限访问权限安卓
This Manifest
flag default value is “true
” for apps targeting Android 9 (and lower).
对于以Android 9(及更低版本)为目标的应用,此Manifest
标志的默认值为“ true
”。
ACCESS_MEDIA_LOCATION权限 (ACCESS_MEDIA_LOCATION permission)
AndroidManifest.xml AndroidManifest.xmlIt is runtime permission (not visible in settings).
这是运行时权限 (在设置中不可见)。
No guarantees that you will always have this permission even if you have
READ_EXTERNAL_STORAGE
permission.即使您具有
READ_EXTERNAL_STORAGE
权限,也无法保证您将始终拥有此权限。
To get an exact number of bytes of files, Use
MediaStore.setReqiuedOriginal()
, if it isn’t a success then an exception occurs.要获取文件的确切字节数,请使用
MediaStore.setReqiuedOriginal()
,如果操作不成功,则会发生异常。
修改和删除媒体资源 (Modify and Delete Media Resources)
- User concerns needed while editing or deleting media resources. 编辑或删除媒体资源时需要用户关注。
- Consent required even for file path access. 即使文件路径访问也需要同意。
- Bulk edit/delete in the same dialog (next Android release). 在同一对话框(Android下一个版本)中批量编辑/删除。
该做什么和不该做什么 (Dos and Don’ts)
- Don’t use a static path. Lock down the file path access. 不要使用静态路径。 锁定文件路径访问。
Use MediaStore (recommended).
使用MediaStore (推荐)。
- MediaStore should be used properly, for example, don’t put your music files in the picture directory. 应正确使用MediaStore,例如,不要将音乐文件放在图片目录中。
- Non-media files should be in the download directory (recommended). 非媒体文件应位于下载目录中(推荐)。
特殊应用访问 (Special App Access)
- Only apps granted by Google will have complete access to storage. 只有Google授予的应用程序才能完全访问存储。
- Submit the declaration form to Google Play. 将声明表单提交给Google Play。
Whitelisted apps by Google.
Google 列入白名单的应用 。
下一发行版更改 (Next Release Changes)
- Update to permission UI: User will see a different permission UI based on updates and whether they’re using scoped storage or not. I.e., before, ten apps would see board access to storage and after, ten media collections have access to storage. 更新到权限UI:基于更新以及是否使用范围存储,用户将看到不同的权限UI。 也就是说,之前,有十个应用程序可以访问开发板,然后可以访问十个媒体集。
- Enable file path and native libraries for reading media. 启用文件路径和本机库以读取媒体。
- Updating media file and modifying APIs. 更新媒体文件并修改API。
- Protecting external app directories. 保护外部应用程序目录。
- Enforcement to target SDK. 强制执行目标SDK。
Read files not created by your app need
READ_EXTERNAL_STORAGE
permission.读取不是由您的应用创建的文件,需要
READ_EXTERNAL_STORAGE
权限。- To edit and delete files not contributed by your app, you need explicit user concern. 要编辑和删除不是由您的应用程序贡献的文件,您需要明确的用户关注。
WRITE_EXTERNAL_STORAGE
will be deprecated in the next Android release and will give read permission only when used.WRITE_EXTERNAL_STORAGE
将在下一个Android版本中弃用,并且仅在使用时才授予读取权限。
非媒体文件访问 (Non-media file access)
To access non-media files by other apps, use System Picker with SAF( Storage Access Framework). Runtime permission will be requested for complete access to that app.
要通过其他应用程序访问非媒体文件,请使用带有SAF(存储访问框架)的系统选择器 。 将需要运行时权限才能完全访问该应用程序。
要记住的事情 (Things to Remember)
If Android 10 is within the scope of your application, kindly use MediaStore and System Picker for file and document access.
如果Android 10在您的应用程序范围内,请使用MediaStore和System Picker进行文件和文档访问。
Happy coding!
编码愉快!
Have a look at the scoped storage example:
看一下范围存储示例:
翻译自: https://medium.com/better-programming/all-you-need-to-know-about-scoped-storage-in-android-10-e621f40bc8b9
android协程作用域