我不明白为什么在 Android 11 中使用 `storage\emulated...\downloads` 文件夹可以 read/write 某些文件而不是其他文件?
I don't understand why in Android 11 use of `storage\emulated...\downloads` folder can read/write some files and not others?
问题: 我似乎无法理解为什么,针对 API 30 (Android 11),我的应用仍然可以从 storage\emulated...\download
文件夹整天存放各种文件,但每次在 *.db
文件上都失败...我能够在 API 29 上没有问题。
作为一个新应用程序,也是我的第一个应用程序,我真的不想依赖旧的解决方法。我宁愿这项工作从一开始就正确。此应用需要能够允许用户将文件附件导入和导出到此应用的数据库。
所以,回到我原来的问题...我不明白为什么使用 new FileInputStream(filename)
对一个文件使用相同的路径而不是另一个文件没有问题?这是应用程序和用户需要的唯一共享文件夹,它缓存所有其他内容。
使用此文件和相同路径
不使用此文件和相同的路径
更新: 添加了代码以阐明复制的意图。
InputStream source = new FileInputStream(sourcePath);
OutputStream destination = new FileOutputStream(destinationPath);
DatabaseManager.copyDatabase(dbSource, destination);
我可以使用 getContentResolver
进行更新和替换,但同样的问题仍然存在——适用于一台设备,而不适用于另一台设备。
InputStream source = getContentResolver().openInputStream(uri);
在上面评论中 Mark 的帮助下,这解决了我的问题。由于无法识别 .db
扩展名,我不得不使用 intent.setType("*/*")
并在 resultLauncher(即 ActivityResultLauncher
)验证文件和扩展名。
https://developer.android.com/training/data-storage/shared/documents-files#open-file
private void setupImportDBButton(){
mImportDB.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
resultLauncher.launch(intent);
});
}
包含在 ActivityResultLauncher 中:用于解决 Android 11 (API 30) 要求强制的多设备使用的功能基础。关键是使用 getContentResolver()
.
Uri uri = result.getData().getData();
String destinationPath = this.getDatabasePath(strDBName).getPath();
InputStream source = this.getContentResolver().openInputStream(uri);
OutputStream destination = this.getContentResolver().openOutputStream(Uri.fromFile(new File(destinationPath)));
DatabaseManager.copyDatabase(source, destination);
问题: 我似乎无法理解为什么,针对 API 30 (Android 11),我的应用仍然可以从 storage\emulated...\download
文件夹整天存放各种文件,但每次在 *.db
文件上都失败...我能够在 API 29 上没有问题。
作为一个新应用程序,也是我的第一个应用程序,我真的不想依赖旧的解决方法。我宁愿这项工作从一开始就正确。此应用需要能够允许用户将文件附件导入和导出到此应用的数据库。
所以,回到我原来的问题...我不明白为什么使用 new FileInputStream(filename)
对一个文件使用相同的路径而不是另一个文件没有问题?这是应用程序和用户需要的唯一共享文件夹,它缓存所有其他内容。
使用此文件和相同路径
不使用此文件和相同的路径
更新: 添加了代码以阐明复制的意图。
InputStream source = new FileInputStream(sourcePath);
OutputStream destination = new FileOutputStream(destinationPath);
DatabaseManager.copyDatabase(dbSource, destination);
我可以使用 getContentResolver
进行更新和替换,但同样的问题仍然存在——适用于一台设备,而不适用于另一台设备。
InputStream source = getContentResolver().openInputStream(uri);
在上面评论中 Mark 的帮助下,这解决了我的问题。由于无法识别 .db
扩展名,我不得不使用 intent.setType("*/*")
并在 resultLauncher(即 ActivityResultLauncher
)验证文件和扩展名。
https://developer.android.com/training/data-storage/shared/documents-files#open-file
private void setupImportDBButton(){
mImportDB.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
resultLauncher.launch(intent);
});
}
包含在 ActivityResultLauncher 中:用于解决 Android 11 (API 30) 要求强制的多设备使用的功能基础。关键是使用 getContentResolver()
.
Uri uri = result.getData().getData();
String destinationPath = this.getDatabasePath(strDBName).getPath();
InputStream source = this.getContentResolver().openInputStream(uri);
OutputStream destination = this.getContentResolver().openOutputStream(Uri.fromFile(new File(destinationPath)));
DatabaseManager.copyDatabase(source, destination);