在 Android Q 中, MediaStore.Files.FileColumns.DATA 字段为deprecated,可能为空,或者应用可能无权读取因此,是否有一种方法可以仅使用其媒体内容Uri重命名文件的文件名部分(而不是路径)?
直到现在,DATA字段可用于从已知Uri查找文件的真实路径,但由于已弃用该文件,因此其想法是什至不尝试查找或解析实际文件路径,并且仅使用其内容Uri。
考虑到Uri将采用标准媒体内容格式(非SAF格式):content:// media / external / images / media / 123
目的是重命名Uri指向的文件的名称。
我知道我可以更新MediaStore的TITLE和DISPLAY_NAME字段,但这不会更改文件名,并且如果用户决定将文件移至设备外,则该文件仍将具有旧文件名。
答案 0 :(得分:2)
更新
您好,首先为我以前的业余回答道歉。但是,我想不出任何直接方法来满足要求。但是,我认为可能有一种解决方法总比没有好。
我们只能使用Uri重命名文件的唯一方法是通过 DocumentsContract 通过SAF。现在,我们拥有的是MediaStore Uri,我们需要获取该文件的等效Document Uri。为此,我们可以使用MediaStore.getDocumentUri( context , mediaUri )
。要注意的是,我们需要通过调用此方法来获得Document Uri的权限。我们可以获得安装的存储卷(或单独的任何特定目录,其中包含我们要修改的媒体文件)的DocumentTree Uri的持久Uri权限。这样,现在我们就拥有了媒体文件的Documents Uri的权限,并且可以使用DocumentsContract.renameDocument
重命名该文件。
步骤1-4是一次性的事情(直到手动撤消为止)
android.permission.READ_MEDIA_IMAGES
权限。 向具有媒体文件的存储卷的DocumentTree询问Uri权限。
StorageManager manager = getSystemService(StorageManager.class);
StorageVolume primaryStorageVolume = manager.getPrimaryStorageVolume();
startActivityForResult(primaryStorageVolume.createOpenDocumentTreeIntent(), STORAGE_PERMISSION_REQ_CODE);
但是,请注意,根据Android的文档,用户可以选择除我们要求的位置之外的其他位置。
onActivityResult获得结果Uri的持久许可
if (resultCode == RESULT_OK) {
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
现在获取媒体文件的文档Uri并将其重命名。
Uri docUri = MediaStore.getDocumentUri( context , mediaUri );
DocumentsContract.renameDocument(contentResolver, docUri, "newFileName.ext");
因此,基本上,我们必须两次询问用户权限,一次用于存储 访问和第二次Uri访问。因为我们将获得持久性 Uri权限,此提示是一次性的,持续时间 直到我们撤销它。我们可以使用它的Document Uri访问所有文件 无需用户选择。
上一个答案
我认为我们可以利用DocumentsContract。但是为此,您应该使用Intent.ACTION_OPEN_DOCUMENT
而不是Intent.GET_CONTENT
来请求文件。取得URI后,您可以使用DocumentsContract.renameDocument
DocumentsContract.renameDocument(contentResolver, uri, "newFileName.ext");
但是,提供URI的DocumentProvider应该支持重命名功能。例如,如果我从Recents
中选择一个文件,则不支持重命名。但是,如果我选择其他提供程序的文件,例如默认文件管理器,则将支持重命名操作。您可以通过检查结果意图中是否设置了标志DocumentsContract.Document.FLAG_SUPPORTS_RENAME
来验证。