#android #media #removable-storage
#Android #Медиафайлы #съемное хранилище
Вопрос:
Есть ли способ использовать намерение StorageActionFramework ACTION_OPEN_DOCUMENT запросить информацию для определенного файла? Более конкретно, у меня есть URI для конкретного файла, который я получил из MediaStore. Я хотел бы выяснить, есть ли у него доступ на запись, и, если да, удалить его. Кроме того, я хотел бы сделать это без какого-либо пользовательского интерфейса (в данном конкретном контексте это не требуется).
В документации говорится, как это сделать для класса файлов с помощью intent.addCategory (Intent.CATEGORY_OPENABLE)
, например. И ограничить его определенным типом файла, intent.setType ("image/*")
например. Но я не вижу ничего, что ограничивало бы его определенным файлом.
Кроме того, я понимаю, что как только вы получаете набор файлов из StorageActionFramework, вы можете просматривать свойства для отдельных файлов.
Похоже, что если бы я мог использовать ACTION_OPEN_DOCUMENT для получения URI SAF, я мог бы затем использовать DocumentsContract.deleteDocument()
для его удаления.
Дополнительный контекст
В моей ситуации пользователь вызвал приложение камеры из моего приложения и сделал один или несколько снимков. Затем мой код запрашивает хранилище MediaStore, чтобы определить имя файла (ов) для нового изображения (ов). Затем я хочу переместить файл (ы) в каталог, специфичный для моего приложения. Это отлично работает для файлов, расположенных во «внутреннем» и «внешнем» хранилище, но не для съемного хранилища.
В долгосрочной перспективе это решение неадекватно, поскольку очевидно, что оно будет использовать слишком много постоянного хранилища (хотя это смягчается быстрыми темпами увеличения размера хранилища). Однако моему приложению требуется контроль над файлами изображений, которые берутся через приложение, и, таким образом, оставление их на съемном носителе потенциально приведет к поломке приложения.
Другим усложняющим фактором является отсутствие Android API для создания нескольких фотографий и сохранения их в заданном месте. Существует такой API для создания одной фотографии, но это не будет работать для моего приложения. Таким образом, я вынужден разрешить приложению camera сохранять свои файлы там, где оно хочет, а затем перемещать их позже.
Некоторые другие приложения просто создают копию фотографий и сохраняют копию в частном каталоге. Я мог бы это сделать, но это еще больше усугубляет проблему хранения. Долгосрочным решением, вероятно, будет использование облачного хранилища в сочетании с локальным частным кэшем.
Ответ №1:
Есть ли способ использовать намерение StorageActionFramework ACTION_OPEN_DOCUMENT запросить информацию для определенного файла?
Нет. Для начала, платформа доступа к хранилищу имеет мало общего с файлами.
Наиболее подходящим для общей структуры было бы, если бы вы могли указать начальный Uri
, чтобы пользователи могли выбирать и открывать документ рядом с этим. Это было бы хорошей функцией, но не поддерживается.
В документации говорится, как это сделать для класса файлов, используя intent.addCategory (намерение.CATEGORY_OPENABLE), например.
Нет. CATEGORY_OPENABLE
означает, что Uri
возвращаемый вами openInputStream()
, openOutputStream()
и связанные с ним методы должны работать, и что query()
на Uri
должно быть возможность возвращать OpenableColumns
. Это имеет мало общего с файлами.
И чтобы ограничить его определенным типом файла, intent.setType («изображение / *»)
Это ограничивает содержимое определенным типом MIME (или шаблоном). Это имеет мало общего с файлами.
Я хотел бы выяснить, есть ли у него доступ на запись, и, если да, удалить его
У вас может быть доступ на запись для изменения содержимого через openOutputStream()
. Я не знаю, есть ли у вас средство удаления базового содержимого.
Кроме того, я хотел бы сделать это без какого-либо пользовательского интерфейса
Единственная причина использования ACTION_OPEN_DOCUMENT
— показать пользовательский интерфейс, позволяющий пользователю выбирать фрагмент содержимого.
Затем мой код запрашивает хранилище MediaStore, чтобы определить имя файла для нового изображения
Поскольку приложению камеры не требуется обновлять MediaStore
, не похоже, что это будет особенно надежно.
Другим усложняющим фактором является отсутствие Android API для создания нескольких фотографий и сохранения их в заданном месте. Существует такой API для создания одной фотографии, но это не будет работать для моего приложения
Поскольку для приложения камеры не требуется, чтобы пользователь мог делать несколько фотографий подряд, это не кажется особенно надежным.
Комментарии:
1. Что касается типа носителя, документация конкретно ссылается на файлы, хотя я полагаю, что это могут быть и потоки. ( developer.android.com/guide/topics/providers /… ) Не уверен, что еще. Вы хотите сказать, что SAF имеет мало общего с файлами?
2. Теперь я понимаю, что более конкретный вопрос был бы лучше. Я изменил исходное сообщение.
3. @PeriHartman: «Вы хотите сказать, что SAF имеет мало общего с файлами?» —
DocumentsProvider
не обязательно, чтобы документы находились в файловой системе в виде файлов (например, столбцов BLOB-объектов в базе данных), и не все файлы в файловой системе будут доступны через некоторыеDocumentsProvider
(например, файлы во внутреннем хранилище для некоторого приложения). «Я изменил исходное сообщение» — я обновил ответ, чтобы он соответствовал.4. @PeriHartman: Где-то по ходу дела пользователю нужно будет подключиться через какой-то пользовательский интерфейс. Это может быть для отдельного документа (
ACTION_OPEN_DOCUMENT
на Android 5.0 ), дерева документов (ACTION_OPEN_DOCUMENT_TREE
на Android 5.1 ), тома (StorageVolume
на Android 7.0 ) и т.д. В последних двух случаях вы получаете права на работу со всем деревом документов.5. Я добавил еще немного контекста в свою операционную систему, пожалуйста, прочтите. Это правда, что я не могу заранее знать, находится ли Uri на съемном носителе. Однако, насколько я знаю, существует только три типа хранилища: внутреннее, внешнее и съемное (или что-либо еще, охватываемое SAF). Первые два случая работают с традиционным кодом файловой системы. Итак, если этот код завершается с ошибкой, разумно предположить, что попробовать использовать SAF. Если это не удается, то так тому и быть. Всегда возможны случаи сбоя.