将文件写入 Android Q - Scoped Storage 中可公开访问的文档文件夹
Writing files to publicly accessible documents folder in Android Q - Scoped Storage
背景
迁移到 Android 问:我找不到合适的方法来获得对文档文件夹的写入权限 (/storage/emulated/0/Documents
)
在有人提到关于分区存储的许多其他问题之前,我已经通读了其中的许多问题,到目前为止我所看到的所有解决方案都使用特定于应用程序的目录或仅访问媒体目录(不是文档文件夹访问权限)。
根据我在Android Q 中的理解,我可以选择:
- 使用只能由我的应用程序(或我授予权限的应用程序)访问的应用程序特定目录
- 允许用户 select 他们想要存储文件的位置(我认为这可以是 public 位置)
ACTION_OPEN_DOCUMENT_TREE
问题
我开发的应用程序用于对受试者进行测试,测试数据自动存储在public可访问的文档文件夹中,有点像:/storage/emulated/0/Documents/myAppName/subjectName/testData-todaysDate.pdf
当用户想要访问测试数据时,他们将智能phone 插入计算机并导航到文档文件夹,其余的就很明显了。因此,我必须使用 public 可访问的存储空间。还假设他们想通过另一个应用程序打开 phone 上的测试数据,同样如此!
我正在寻找的解决方案
所以我正在寻找的解决方案需要能够执行以下操作:
- 不会多次请求许可(一次就可以)
- 无需用户提示自动保存测试数据(因为将进行数百次测试)
- 保存到 public 文档文件夹,例如
/storage/emulated/0/Documents/
- 不涉及用户 select 访问目录,因此不
ACTION_OPEN_DOCUMENT_TREE
- 理想情况下,数据是持久的,因此卸载应用程序不会导致数据丢失
我知道 Android Q 中的这些变化是为了让用户更多地 "into the loop" 了解应用程序如何访问他们的数据,但是一旦他们了解您的应用程序如何使用您的数据,就不应该一个问题。
尝试将此行放入 android Q:
的清单文件中
android:requestLegacyExternalStorage="true"
在应用程序标签中。
仅限 Android Q。
String collection = "content://media/1c11-2404/file"; // One can even write to micro SD card
String relative_path = "Documents/MyFolder";
Uri collectionUri = Uri.parse(collection);
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
contentValues.put(MediaStore.MediaColumns.SIZE, filesize);
contentValues.put(MediaStore.MediaColumns.DATE_MODIFIED, modified );
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relative_path);
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1)
Uri fileUri = context.getContentResolver().insert(collectionUri, contentValues);
有了 uri 就可以打开输出流来写入文件的内容。
背景
迁移到 Android 问:我找不到合适的方法来获得对文档文件夹的写入权限 (/storage/emulated/0/Documents
)
在有人提到关于分区存储的许多其他问题之前,我已经通读了其中的许多问题,到目前为止我所看到的所有解决方案都使用特定于应用程序的目录或仅访问媒体目录(不是文档文件夹访问权限)。
根据我在Android Q 中的理解,我可以选择:
- 使用只能由我的应用程序(或我授予权限的应用程序)访问的应用程序特定目录
- 允许用户 select 他们想要存储文件的位置(我认为这可以是 public 位置)
ACTION_OPEN_DOCUMENT_TREE
问题
我开发的应用程序用于对受试者进行测试,测试数据自动存储在public可访问的文档文件夹中,有点像:/storage/emulated/0/Documents/myAppName/subjectName/testData-todaysDate.pdf
当用户想要访问测试数据时,他们将智能phone 插入计算机并导航到文档文件夹,其余的就很明显了。因此,我必须使用 public 可访问的存储空间。还假设他们想通过另一个应用程序打开 phone 上的测试数据,同样如此!
我正在寻找的解决方案
所以我正在寻找的解决方案需要能够执行以下操作:
- 不会多次请求许可(一次就可以)
- 无需用户提示自动保存测试数据(因为将进行数百次测试)
- 保存到 public 文档文件夹,例如
/storage/emulated/0/Documents/
- 不涉及用户 select 访问目录,因此不
ACTION_OPEN_DOCUMENT_TREE
- 理想情况下,数据是持久的,因此卸载应用程序不会导致数据丢失
我知道 Android Q 中的这些变化是为了让用户更多地 "into the loop" 了解应用程序如何访问他们的数据,但是一旦他们了解您的应用程序如何使用您的数据,就不应该一个问题。
尝试将此行放入 android Q:
的清单文件中 android:requestLegacyExternalStorage="true"
在应用程序标签中。
仅限 Android Q。
String collection = "content://media/1c11-2404/file"; // One can even write to micro SD card
String relative_path = "Documents/MyFolder";
Uri collectionUri = Uri.parse(collection);
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
contentValues.put(MediaStore.MediaColumns.SIZE, filesize);
contentValues.put(MediaStore.MediaColumns.DATE_MODIFIED, modified );
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relative_path);
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1)
Uri fileUri = context.getContentResolver().insert(collectionUri, contentValues);
有了 uri 就可以打开输出流来写入文件的内容。