- Android 11 — хранилище с заданной областью — невозможно использовать java.io.File даже после предоставления разрешений Uri
- 1 ответ
- Uri с com.android.externalstorage.documents, расположенными на не первичной томе
- Uri изображения не отображает изображения в ImageView на некоторых устройствах android
- 11 ответов
- Полный список
- Внутренняя память
- SD карта
Android 11 — хранилище с заданной областью — невозможно использовать java.io.File даже после предоставления разрешений Uri
В настоящее время я переношу приложение Android на Scoped Storage. Уход от java.io.file — это настоящий кошмар, и я чувствую себя большим недостатком. В настоящее время я пытаюсь понять, возвращаются ли пути getExternalMediaDirs() можно эффективно использовать с прямыми путями к файлам..
После запроса пользователя выбрать данную папку
И сохранение постоянных разрешений Uri на чтение / запись в onActivityResult
Ожидается ли, что по-прежнему не удастся использовать java.io.File в таком предоставленном пути ?
Эквивалент пути java.io.File
Некоторые заключительные примечания:
- такой путь можно записать с помощью SAF
- такой путь нельзя записать с прямым путем java.io.File (исключение EACCES )
- /Android/media/com.otherapp отличается от собственного /Android/media/com.app
- android.permission.MANAGE_EXTERNAL_STORAGE недоступен
1 ответ
Да, потому что после предоставления разрешений у вас будет доступ к Content Scheme Uri этой конкретной папки, а не к путям файловой системы, поэтому вы не сможете перечислить объекты java.io.File, используя этот Uri.
Но вы можете использовать его для listFiles() , который вернет вам список DocumentFile. Затем вы можете использовать эти объекты DocumentFile , чтобы получить Uri этого конкретного файла, используя documentFile.getUri (). Используя этот Uri , вы можете легко выполнять с этим файлом базовые операции, такие как display,copy,delete,share .
Ниже приведен пример списка файлов из папки другого приложения.
Я пропускаю часть кода для получения разрешений, предполагая, что у вас уже есть разрешения на доступ к папке этого другого приложения
В этом примере я перечисляю файлы из Android / media / com.whatsapp / WhatsApp / Media / .Statuses
После получения разрешения у нас есть дерево Ури
Здесь дерево Ури — это content://com.android.externalstorage.documents/tree/primary:Android/media
Этот каталог является DocumentFile, теперь он используется для перечисления всех папок внутри этого дерева Uri.
Теперь у нас есть список DocumentFile из папки другого приложения. Используйте Uri этого файла для дальнейших операций, таких как display,copy,delete,share .
Также прочтите комментарии к вашей точке зрения о Downloads папке but would this be the same matter for files in Download
Загрузки — это общедоступный каталог, я перечислил файлы, созданные моим собственным приложением с помощью listFiles (), и он вернул мне список Файл.
Источник
Uri с com.android.externalstorage.documents, расположенными на не первичной томе
У меня проблема. У меня есть Uri который читает что-то вроде:
Я могу найти StorageVolume через StorageManager.getStorageVolumes()
Если объем является основным: StorageVolume.isPrimary() — я понимаю, что могу разобрать путь как:
Но как найти путь, если объем не является основным? В конце концов, мне нужно иметь простой объект File ссылается его абсолютный путь.
PS Конечно, у меня есть все необходимое разрешение: либо статические объявлены через манифест или во время выполнения обоих.
Я понимаю, что могу разобрать путь как
Не надежно. Вы принимаете определенную внутреннюю реализацию кода, который может отличаться от производителя устройства и версии ОС.
В конце концов, мне нужно иметь простой объект File, на который ссылается его абсолютный путь.
Шаг # 1: используйте ContentResolver и openInputStream() чтобы получить InputStream на содержимое, идентифицированное Uri
Шаг № 2: Откройте FileOutputStream на некоторый файл, который вы контролируете (например, в getCacheDir() )
Шаг 3: Скопируйте содержимое из InputStream в FileOutputStream
Шаг 4: используйте полученный файл, удалив его, когда он больше не нужен
Конечно, у меня есть все необходимое разрешение
Конечно, нет, поскольку у вас нет разрешений на доступ к файлам на съемном носителе, вне очень специфических мест (например, второй и последующие пути, возвращаемые getExternalFilesDirs() ).
Источник
Uri изображения не отображает изображения в ImageView на некоторых устройствах android
у меня есть ImageView. Когда вы нажимаете на ImageView, он открывает галерею, и вы выбираете изображение и показываете его на ImageView. У меня есть условие, что когда я закрываю свое приложение, а затем открываю его, изображение сохранится там . Поэтому для этого я сохраняю Uri изображения на sharedprefrence. И при открытии приложения я получаю тот же Uri и пытается отобразить изображение на imageView.
однако в некоторых телефонах-изображение выглядит идеально, как Mi (Lollipop), Samsung (KitKat) но это не отображается в телефонах типа-Motorola (Marshmallow) ,One Plus One (Marshmallow). Есть идеи, почему это происходит ? Вот мой код
для сбора изображения, которое я использую
и на onActivityResult () код
и при извлечении из sharedprefrence я конвертирую строку в uri с помощью Uri.parse(profile_image)
однако, если я замечу, uri возвращается для разных телефонов android следующим образом
следовательно, когда содержимое uri is-content: / / media / external/images/ media / is отображение изображения на ImageView идеально, а в других случаях это не
11 ответов
попробуй такое
я разработал и tested и работает на
- Lenovo K3 Примечание (Зефир)
- Motorola (Леденец)
- Samsung (KitKat)
в своем MainActivity.java добавить
Теперь Ручка onActivityResult .
в своем Добавить permission
Примечание:
Assuming вы добавили код take permission на Marshmallow
результат Uri
lenovo K3 Примечание: content://com.android.externalstorage.documents/document/primary%3ADCIM%2FCamera%2FIMG_20160606_212815.jpg
samsung: content://com.android.providers.media.documents/document/image%3A2086
motorola: content://com.android.providers.media.documents/document/image%3A15828
Я думаю, что проблема с uri файла изображения, я использую класс для получения точного URI, и он протестирован и работает на всех версиях.
используйте getPath, чтобы найти точный путь к файлу. Это простой способ справиться с проблемой, как вы определили. Пожалуйста, попробуйте и дайте мне знать, если вам нужна дополнительная помощь 🙂
‘в предыдущих версиях Android, Если вы хотите, чтобы ваше приложение, чтобы получить определенный тип файла из другого приложения, он должен вызвать намерение с ACTION_GET_CONTENT действие. Это действие по-прежнему является подходящим способом запроса файла, который вы хотите импорт в вашем приложении. Тем не менее, Android 4.4 вводит ACTION_OPEN_DOCUMENT действие, которое позволяет пользователю выберите файл определенного типа и предоставьте вашему приложению долгосрочный доступ для чтения к этому файлу (возможно, с доступом на запись) без импорта файла в приложение.(подчеркнуто)
чтобы ваше приложение могло извлекать ранее выбранные изображения, просто измените действие с ACTION_GET_CONTENT to ACTION_OPEN_DOCUMENT (решение подтвердило работу на Nexus 7 2013).
передайте свой URI в этом методе, он вернет строку и преобразует ее в Bitmap
вам нужно запросить разрешение на чтение внешнего хранилища пользователю во время выполнения для Android 6+
надеюсь, что это помогает.
возможно, вы можете справиться с этим, сначала преобразовав URI в реальный путь.
и ваш onActivityResult должен выглядеть так
мне удалось сделать это в прошлом. Вместо того, чтобы хранить его в SharePreferences, я сохраняю его в пакете, когда onSaveInstanceState(Bundle) вызывается: bundle.putParcelable (SOME_KEY, uri). Вы можете сделать это, потому что Uri реализует Parcelable. После этого проверьте этот uri в пакете, переданном в onCreate (). Код:
P/S: Я думаю, проблема хранения uri в SharePreference заключается в кодировании / декодировании Uri.
вы можете легко конвертировать URI в Bitmap:
а затем установите в Imageview: imgview.setImageBitmap(изображения);
надеюсь, это поможет вам.
может быть проблема с версиями Пикассо. Они исправили что-то с загрузкой больших изображений в версии 2.5.0 (2.4.0. ), который еще не доступен через репозитории.
вам нужно будет вручную включить ночной снимок Пикассо, и это, вероятно, исправит вашу проблему. Для меня-да.
Я также столкнулся с чем-то подобным ранее и нашел полезный вспомогательный класс, который дает вам точное местоположение файла. Вот это ссылке.
вы можете использовать такие методы, как FileUtils.getPath (контекст, uri) или FileUtils.getFile (context, uri), чтобы получить файл. Тогда просто используйте его так:
надеюсь, что это помогает.
просто не на 100% уверен, если я получу вопрос. Если определенные изображения не могут быть показаны в imageView (даже до закрытия и перезапуска приложения), то проблема в том, что Picasso может обрабатывать содержимое от определенных поставщиков. Я не понимаю, что это так, но если это так, то вы можете рассмотреть возможность подачи ошибки/RFE для этой библиотеки. С другой стороны, если Picasso правильно показывает изображение для данного Uri, но не после Uri_org — > String — > Uri_regen преобразование тогда это означает, что Uri_org не то же самое, что Uri_regen. Вы можете (временно) добавить пару строк кода, чтобы преобразовать строку обратно в Uri и поставить точку останова сразу после и сравнить два Uri. Это должно дать вам ключ к тому, как все идет не так.
Если вы не нажмете точку останова, затем переместите точку останова обратно в Оператор » if » и визуально проверьте два Uri (которые почти наверняка будут одинаковыми, иначе у вас было бы нажмите точку останова,но это поможет проверить сам код отладки). Если URI такие же, то строки предпочтение не правильно сохранился почему-то. В этом случае запишите исходный Uri и добавьте точку останова в строке, которая преобразует строку обратно в Uri:
Если предыдущий эксперимент работал, он должен снова работать здесь, если profile_image не отличается. В любом случае вы должны получить указатели на то, где проблема есть.
Источник
Полный список
— работаем с файлами
Работа с файлами в Android не сильно отличается от таковой в Java. В этом уроке рассмотрим, как записать/прочесть файл во внутреннюю память и на SD-карту.
Project name: P0751_Files
Build Target: Android 2.3.3
Application name: Files
Package name: ru.startandroid.develop.p0751files
Create Activity: MainActivity
Рисуем экран main.xml:
4 кнопки, смысл которых понятен по тексту на них.
В onclick обрабатываем нажатия 4-х кнопок и вызываем соответствующие методы.
writeFile – запись файла во внутреннюю память. Используется метод openFileOutput, который на вход берет имя файла и режим записи: MODE_PRIVATE – файл доступен только этому приложению, MODE_WORLD_READABLE – файл доступен для чтения всем, MODE_WORLD_WRITEABLE — файл доступен для записи всем, MODE_APPEND – файл будет дописан, а не начат заново.
readFile – чтение файла из внутренней памяти. Используем метод openFileInput, принимающий на вход имя файла. Здесь и в методе записи внутреннего файла вы можете задать только имя файла, а каталог для ваших файлов вам уже выделен.
writeFileSD – запись файла на SD. Используем метод getExternalStorageState для получения состояния SD-карты. Здесь можно посмотреть какие бывают состояния. Нам нужно MEDIA_MOUNTED – когда SD-карта вставлена и готова к работе. Далее мы получаем путь к SD-карте (метод getExternalStorageDirectory), добавляем свой каталог и имя файла, создаем каталог и пишем данные в файл.
readFileSD – чтение файла с SD. Все аналогично предыдущему методу, только файл не пишем, а читаем.
Осталось в манифест добавить разрешение на работу с файлами на SD — android.permission.WRITE_EXTERNAL_STORAGE.
Все сохраним и запустим. Видим экран с 4-мя кнопками:
Внутренняя память
Жмем кнопку Записать файл. Видим в логе:
Проверим. Идем в File Explorer (Window > Show View > Other > Android > File Explorer) и открываем там папку data/data/ru.startandroid.develop.p0751files/files и видим там наш файл file.
Возвращаемся в эмулятор. Жмем Прочесть файл и в логе видим:
Это тот текст, который мы записывали в файл.
SD карта
Теперь жмем Записать файл на SD.
Файл записан на SD: /mnt/sdcard/MyFiles/fileSD
Проверяем. Идем в FileExplorer и открываем там папку mnt/sdcard/MyFiles/ а в ней файл fileSD.
Возвращаемся в эмулятор и жмем кнопку Прочесть файл с SD. В логе видим:
Содержимое файла на SD
Этот текст мы и записывали.
mnt/sdcard — обычно этот путь ведет к содержимому SD-карты. Возможно у вас он будет другой.
В общем, при работе с файлами на SD вы используете стандартные java механизмы. А при работе с внутренним хранилищем для удобства можно использовать методы-оболочки от Activity:
openFileOutput – открыть файл на запись
openFileInput – открыть файл на чтение
И есть метод getFilesDir – возвращает объект File, соответствующий каталогу для файлов вашей программы. Используйте его, чтобы работать напрямую, без методов-оболочек.
Подробности работы в java с файловой системой я здесь описывать не буду. На нашем форуме пользователь SKR сделал отличную памятку по работе с файлами. Скорее всего, вы найдете там все что нужно.
Если у вас проверка SD-карты показывает, что карта недоступна (см. лог), то убедитесь в свойствах AVD, что у вас для SDCard указан Size или File. Если указаны, то попробуйте перезапустить AVD.
На следующем уроке:
— создаем экран с вкладками
— используем иконку в названии вкладки
— используем обработчик перехода между вкладками
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник