如何在仅知道媒体内容Uri的Android中重命名文件 [英] How to rename a file in Android knowing only its media content Uri

查看:90
本文介绍了如何在仅知道媒体内容Uri的Android中重命名文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Android Q 中, MediaStore.Files.FileColumns.DATA 字段为

In Android Q the MediaStore.Files.FileColumns.DATA field has been deprecated, and may be null or apps may not have the rights to read it, therefore is there a way to rename the filename section (not the path) of a file using only its media content Uri?

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

Until now the DATA field could be used to find the real path of a file from a known Uri, but since it has been deprecated then the idea is not to even try to find or resolve the real file path, and use only its content Uri.

请考虑将Uri设为标准媒体内容格式(非SAF格式):content://media/external/images/media/123

Consider that the Uri will be in the standard media content format (not SAF format): content://media/external/images/media/123

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

The intention is to rename the name of the file that the Uri is pointing to.

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

I’m aware that I can update the MediaStore’s TITLE and DISPLAY_NAME fields, but this doesn’t change the file name, and if a user decides to move the file outside the device then this one will still have the old filename.

推荐答案

更新

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

Hi, firstly apologies for my previous amateurish answer. But, I can't think of any direct approach to accomplish the requirement. However, there might be a workaround which, I think, is better than nothing.

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

The only way we can rename a file solely with a Uri is by DocumentsContract via SAF. What we've now in hand is the MediaStore Uri and We need to get the equivalent Document Uri of that file. For that we can use MediaStore.getDocumentUri( context , mediaUri ). The catch is, we need to have permission for the Document Uri before getting it, by calling this method. We can get a persistable Uri permission for the DocumentTree Uri of the mounted storage volume ( or any specific directory alone, which contains the media files we want to modify ). By doing so, now we'll have the permission for the Documents Uri of the media file and we can use DocumentsContract.renameDocument to rename that file.

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

Steps 1-4 will be one time things ( until manually revoked )

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

  1. Declare android.permission.READ_MEDIA_IMAGES permission in Manifest.
  2. Ask READ_MEDIA_IMAGES permission to the user.
  3. Ask Uri permission for DocumentTree of the storage volume which has the media file.

    StorageManager manager = getSystemService(StorageManager.class);

    StorageVolume primaryStorageVolume = manager.getPrimaryStorageVolume();

    startActivityForResult(primaryStorageVolume.createOpenDocumentTreeIntent(), STORAGE_PERMISSION_REQ_CODE);

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

But, please note that according to Android's documentation the user can select a location other than the one that we requested.

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

  1. onActivityResult take persistable permission of the result Uri

    if (resultCode == RESULT_OK) {
        getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    }

  • 现在获取媒体文件的文档Uri并将其重命名.

  • Now get Documents Uri of the media file and rename it.

    Uri docUri = MediaStore.getDocumentUri( context , mediaUri );
    DocumentsContract.renameDocument(contentResolver, docUri, "newFileName.ext");
    

  • 因此,基本上,我们必须两次询问用户权限,一次用于存储访问和第二次Uri访问.因为我们将获得持久性Uri权限,此提示是一次性的,持续时间直到我们撤销它.我们可以使用它的Document Uri访问所有文件无需用户选择.

    So basically we'll have to ask user permission twice, once for storage access and second for Uri access. Since we'll be getting a persistable Uri permission, this prompt will be a one time thing and it lasts until we revoke it. We can access all the files using it's Document Uri without having the user select it.


    上一个答案


    Previous Answer

    我认为我们可以利用DocumentsContract.但是为此,您应该使用 Intent.ACTION_OPEN_DOCUMENT 而不是 Intent.GET_CONTENT 来请求文件.取得URI后,您可以使用

    I think we can make use of the DocumentsContract. But for that, you should request the file with Intent.ACTION_OPEN_DOCUMENT instead of Intent.GET_CONTENT. Once you have got the URI, you can rename that file using DocumentsContract.renameDocument

    DocumentsContract.renameDocument(contentResolver, uri, "newFileName.ext");
    

    但是,提供URI的DocumentProvider应该支持重命名功能.例如,如果我从 Recents 中选择一个文件,则不支持重命名.但是,如果我选择其他提供程序的文件,例如默认文件管理器,则将支持重命名操作.您可以通过检查结果意图中是否设置了标志 DocumentsContract.Document.FLAG_SUPPORTS_RENAME 来验证.

    But, the DocumentProvider which provided the URI should support rename function. For example, If I choose a file from Recents, rename is not supported. But, If I choose the same file with some other provider, say the default file manager, rename action will be supported. You can verify that by checking if the flag DocumentsContract.Document.FLAG_SUPPORTS_RENAME is set in the result intent.

    这篇关于如何在仅知道媒体内容Uri的Android中重命名文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆