如何在仅知道媒体内容Uri的情况下在Android中重命名文件

时间:2019-03-23 14:00:06

标签: android file uri rename mediastore

Android Q 中, MediaStore.Files.FileColumns.DATA 字段为deprecated,可能为空,或者应用可能无权读取因此,是否有一种方法可以仅使用其媒体内容Uri重命名文件的文件名部分(而不是路径)?

直到现在,DATA字段可用于从已知Uri查找文件的真实路径,但由于已弃用该文件,因此其想法是什至不尝试查找或解析实际文件路径,并且仅使用其内容Uri。

考虑到Uri将采用标准媒体内容格式(非SAF格式):content:// media / external / images / media / 123

目的是重命名Uri指向的文件的名称。

我知道我可以更新MediaStore的TITLE和DISPLAY_NAME字段,但这不会更改文件名,并且如果用户决定将文件移至设备外,则该文件仍将具有旧文件名。

1 个答案:

答案 0 :(得分:2)

更新

您好,首先为我以前的业余回答道歉。但是,我想不出任何直接方法来满足要求。但是,我认为可能有一种解决方法总比没有好。

我们只能使用Uri重命名文件的唯一方法是通过 DocumentsContract 通过SAF。现在,我们拥有的是MediaStore Uri,我们需要获取该文件的等效Document Uri。为此,我们可以使用MediaStore.getDocumentUri( context , mediaUri )。要注意的是,我们需要通过调用此方法来获得Document Uri的权限。我们可以获得安装的存储卷(或单独的任何特定目录,其中包含我们要修改的媒体文件)的DocumentTree Uri的持久Uri权限。这样,现在我们就拥有了媒体文件的Documents Uri的权限,并且可以使用DocumentsContract.renameDocument重命名该文件。

步骤1-4是一次性的事情(直到手动撤消为止)

  1. 在清单中声明android.permission.READ_MEDIA_IMAGES权限。
  2. 向用户询问READ_MEDIA_IMAGES权限。
  3. 向具有媒体文件的存储卷的DocumentTree询问Uri权限。

        StorageManager manager = getSystemService(StorageManager.class);
    
        StorageVolume primaryStorageVolume = manager.getPrimaryStorageVolume();
    
        startActivityForResult(primaryStorageVolume.createOpenDocumentTreeIntent(), STORAGE_PERMISSION_REQ_CODE);
    

但是,请注意,根据Android的文档,用户可以选择除我们要求的位置之外的其他位置。

  1. onActivityResult获得结果Uri的持久许可

        if (resultCode == RESULT_OK) {
            getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
    
  2. 现在获取媒体文件的文档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来验证。