Как переименовать файл в Android, зная только его медиаконтент Uri - PullRequest
8 голосов
/ 23 марта 2019

В Android Q поле MediaStore.Files.FileColumns.DATA устарело устарело и может быть пустым, или приложения могут не иметь прав на чтениеТаким образом, есть ли способ переименовать раздел имени файла (не путь) файла, используя только его медиа-контент Uri?

До сих пор поле DATA можно было использовать для поиска реального пути к файлу из известного Uri, но, поскольку он устарел, идея не в том, чтобы даже пытаться найти или разрешить реальный путь к файлу,и использовать только его содержимое Uri.

Учтите, что Uri будет в стандартном формате медиа-контента ( не в формате SAF ): content: // media / external / images / media / 123

Цель состоит в том, чтобы переименовать имя файла, на который указывает Uri.

Мне известно, что я могу обновить поля TITLE и DISPLAY_NAME в MediaStore, но это не изменитсяимя файла, и если пользователь решит переместить файл за пределы устройства, у этого файла останется старое имя файла.

1 Ответ

2 голосов
/ 23 марта 2019

Обновление

Привет, сначала извинения за мой предыдущий любительский ответ.Но я не могу придумать прямого подхода к выполнению этого требования.Однако может быть обходной путь, который, я думаю, лучше, чем ничего.

Единственный способ переименовать файл исключительно с помощью Uri - это DocumentsContract через SAF.Теперь у нас есть MediaItore Uri, и нам нужно получить эквивалентный Document Uri этого файла.Для этого мы можем использовать MediaStore.getDocumentUri( context , mediaUri ).Уловка в том, что нам нужно получить разрешение для Document Uri, прежде чем получить его, вызвав этот метод.Мы можем получить постоянное разрешение Uri для DocumentTree Uri подключенного тома хранилища (или любого отдельного каталога, который содержит файлы мультимедиа, которые мы хотим изменить).Таким образом, теперь у нас будет разрешение на Uri для документов мультимедийного файла, и мы можем использовать DocumentsContract.renameDocument для переименования этого файла.

Шаги 1-4 будут выполняться один раз (до тех пор, пока не будут отменены вручную).)

  1. Объявить разрешение android.permission.READ_MEDIA_IMAGES в Манифесте.
  2. Запрос разрешения READ_MEDIA_IMAGES для пользователя.
  3. Запрос разрешения Uri для DocumentTree тома хранения, в котором находится файл мультимедиа.

        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);
    }

Теперь получите Documents 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");

Но DocumentProvider, предоставивший URI, должен поддерживать функцию переименования.Например, если я выбираю файл из Recents, переименование не поддерживается.Но если я выберу тот же файл с другим провайдером, скажем, файловым менеджером по умолчанию, действие переименования будет поддерживаться.Это можно проверить, проверив, установлен ли флаг DocumentsContract.Document.FLAG_SUPPORTS_RENAME в результате намерения.

...