正如您所提到的,
Environment.getExternalStoragePublicDirectory
已被标记为过时。因此,没有常规方法可以获得下载目录的路径以将文件保存在其中。作为替代方案,您可以使用
ACTION_CREATE_DOCUMENT
来显示路径选择器,然后使用返回的uri将文件写入所选位置。
以下是显示选择器的方法:
const val CREATE_FILE = 1
private fun createFile(pickerInitialUri: Uri) {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/plain"
putExtra(Intent.EXTRA_TITLE, "sam.txt")
putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri)
}
startActivityForResult(intent, CREATE_FILE)
}
以下是获取选定URI并写入文件的方法:
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (requestCode == CREATE_FILE && resultCode == Activity.RESULT_OK) {
resultData?.data?.also { outputUri ->
FileInputStream(inputFile).use { inputStream ->
context.contentResolver.openFileDescriptor(outputUri, "w")?.use {
FileOutputStream(it.fileDescriptor).use { outputStream ->
FileUtils.copy(inputStream, outputStream)
}
}
}
}
}
}
更多信息可以在这里找到。
编辑:
可以使用ACTION_OPEN_DOCUMENT_TREE
来选择要持久保存文件的目录。然后使用takePersistableUriPermission
方法获得持续授权,以便在设备重新启动后继续使用它。然后使用DocumentFile
执行文件操作。
打开目录请求:
private static final int OPEN_DIRECTORY_REQUEST_CODE = 1;
void openDirectory() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
startActivityForResult(intent, OPEN_DIRECTORY_REQUEST_CODE);
}
接收选定目录并获取可持续权限:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OPEN_DIRECTORY_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri directoryUri = data.getData();
if (directoryUri == null)
return;
requireContext()
.getContentResolver()
.takePersistableUriPermission(directoryUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} else
super.onActivityResult(requestCode, resultCode, data);
}
最后持久化该文件:
private void persistFile(@NonNull Uri directoryUri,
@NonNull File fileToPersist,
@NonNull String mimeType,
@NonNull String displayName) {
DocumentFile dirFile = DocumentFile.fromSingleUri(requireContext(), directoryUri);
if (dirFile != null) {
DocumentFile file = dirFile.createFile(mimeType, displayName);
if (file != null) {
Uri outputUri = file.getUri();
try (ParcelFileDescriptor fd = requireContext().getContentResolver().openFileDescriptor(outputUri, "w")) {
if (fd != null) {
try (FileInputStream inputStream = new FileInputStream(fileToPersist)) {
try (FileOutputStream outputStream = new FileOutputStream(fd.getFileDescriptor())) {
FileUtils.copy(inputStream, outputStream);
}
}
}
} catch (Throwable th) {
th.printStackTrace();
}
}
}
}
查看此存储库,了解如何使用ACTION_CREATE_DOCUMENT
功能。
Uri.fromFile(file)
替换为MediaStore.Files.getContentUri("external")
。 - blackapps