Невозможно сохранить файловое хранилище, эмулированное загрузкой 0

Обновлено: 02.07.2024

Внешнее хранилище Android можно использовать для записи и сохранения данных, чтения файлов конфигурации и т. д. Эта статья является продолжением руководства "Внутреннее хранилище Android" из серии руководств по хранению структурированных данных в Android.

Внешнее хранилище Android

Внешнее хранилище, такое как SD-карта, также может хранить данные приложений, безопасность файлов, которые вы сохраняете во внешнем хранилище, не обеспечивается.
В целом существует два типа внешнего хранилища:

  • Основное внешнее хранилище: встроенное совместно используемое хранилище, доступ к которому «пользователь может получить, подключив USB-кабель и установив его в качестве накопителя на хост-компьютере». Пример. Когда мы говорим Nexus 5 – 32 ГБ.
  • Дополнительное внешнее хранилище: съемное хранилище. Пример: SD-карта

Все приложения могут читать и записывать файлы, размещенные на внешнем хранилище, а пользователь может их удалять. Нам нужно проверить, доступна ли SD-карта и можем ли мы записать на нее. Только после того, как мы проверили, что внешнее хранилище доступно, мы можем записать в него, иначе кнопка сохранения будет отключена.

Пример структуры проекта внешнего хранилища Android

внешнее хранилище Android

Во-первых, нам нужно убедиться, что у приложения есть разрешение на чтение и запись данных на SD-карту пользователя, поэтому давайте откроем AndroidManifest.xml и добавим следующие разрешения:

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

getExternalStorageState() – это статический метод Environment для определения того, доступно ли в данный момент внешнее хранилище. Как видите, если условие ложно, мы отключаем кнопку сохранения.

Пример кода внешнего хранилища Android

Макет activity_main.xml определяется следующим образом:

Здесь, помимо кнопок сохранения и чтения из внешнего хранилища, мы отображаем ответ на сохранение/чтение во внешнее хранилище/из внешнего хранилища в текстовом виде, в отличие от предыдущего урока, где отображалось всплывающее окно для Android.

Класс MainActivity.java приведен ниже:

  1. Environment.getExternalStorageState(): возвращает путь к внутренней точке монтирования SD-карты, например «/mnt/sdcard»
  2. getExternalFilesDir(): возвращает путь к папке с файлами внутри Android/data/data/application_package/ на SD-карте. Он используется для хранения любых файлов, необходимых для вашего приложения (например, изображений, загруженных из Интернета, или файлов кеша). После удаления приложения все данные, хранящиеся в этой папке, также исчезнут.

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

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

Примечание. Убедитесь, что ваш эмулятор Android настроен таким образом, что у него есть SD-карта, как показано в диалоговом окне изображения из AVD ниже. Перейдите в Инструменты->Android->Виртуальное устройство Android, отредактируйте конфигурации->Показать дополнительные настройки.

 Конфигурация внешнего хранилища Android, файл сохранения Android во внешнее хранилище

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

Учебное пособие по использованию внутренней памяти Android

Учебное пособие по общим настройкам Android

Он любит изучать новые вещи на Android и iOS. Стреляйте в него вопросами.

Комментарии

Мы создали файл во внутренней памяти вне кеша и записали в него некоторые данные. Мы хотим иметь возможность редактировать файл ПОСЛЕ того, как приложение будет удалено и переустановлено.

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

Можем ли мы снова получить доступ к файлу после повторной установки приложения?
Как это сделать?

Цените свое время и помогите в этом.
С уважением,
Шарик

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

редактировать текст и кнопку
когда я пишу что-то в тексте редактирования и нажимаю кнопку сохранения, затем открываю внешнее хранилище памяти. Спросите пользователя, где вы хотите сохранить файл. Я пытаюсь это сделать, но не могу найти, пожалуйста, помогите мне.

Не сохранять pdf-файл Внутреннее хранилище Android studio sdk 30.
Мой код
String myFilePath = Environment.getExternalStorageDirectory().getPath() + «/REQUISITION.пдф»;
Файл файл = новый файл (myFilePath);
попробуйте myPdfDocument.writeTo(new FileOutputStream(file));
Toast.makeText(Createidepdf.this, «Создание файла PDF», Toast.LENGTH_LONG).show();

> catch (IOException e) e.printStackTrace();
>

Я использую Android 8.1.
Я подключил дополнительное хранилище. Мы создаем базу данных для вторичного хранилища в /data/data/my-package_name/databases/external.db

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

Когда я проверяю наличие базы данных с помощью приведенного ниже фрагмента кода

Файловая база данных = новый файл («/data/data/my-package_name/database/external.db»);
логический результат = database.exists();

Но результат всегда ложный.

1) Путь правильный.
2) Учитывая разрешение WRITE_EXTERNAL_STORAGE и READ_EXTERNAL_STORAGE
3) Даже пытался указать путь в файле AndroidManifest.
4) getAbsolutePath() возвращает правильный путь к файлу, но database.getAbsolutePath().exists() всегда возвращает false.

Если у кого-то есть идеи, пожалуйста, предложите мне?

java.io.FileNotFoundException: /document/primary:WhatsApp/Media/WhatsApp Documents/UploadContest.xlsx (Нет такого файла или каталога)

Боже мой, это так круто1. именно то, что я хотел!! компактный код

Файл сохраняется во внутренней памяти, а не на SD-карте!

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

Да, у меня есть решение

могу ли я узнать, где сохранен мой файл?

проверьте logcat, там укажите путь к файлу

Я хочу сохранить данные в sqlite для сохранения данных приложения Android в автономном режиме и синхронизировать сохраненные данные в сети. пожалуйста, помогите.

Хорошо, но в этом примере используется только основное внешнее хранилище. Как насчет вторичного внешнего хранилища, как вы комментируете в начале этого поста?

пожалуйста, опубликуйте пример медиаплеера.

String mediaPath = "/sdcard/Omnamashivaya.mp3";
URI uriPath = Uri.parse(mediaPath);

MediaPlayer player = new MediaPlayer();
попробуйте player.setDataSource(getApplicationContext(),uriPath);
player.prepare();
player.start();

Toast.makeText(getApplicationContext(), "Начать воспроизведение", Toast.LENGTH_LONG).show();

> catch (IOException e) e.printStackTrace();
>

я получил исключение ниже

здравствуйте,
я рекомендую вам использовать exo-player

Хорошо, я понял, например. в SDCARD существует путь android/data/app_name/files/MyFileStorage, а папка пуста.

Android SDK, созданный для платформы x86, существует по пути android/data/имя_приложения/files/MyFileStorage/SampleFile.txt, но в чем разница? :/ А почему файл не на sdcard? ?
Ответить

если (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) вернуть true;
>
вернуть ложь;

можно переписать как:

Аналогично любой if () < return true; >вернуть ложь; можно переписать return()

Черт, я боялся, что поле комментария удалит левые угловые скобки:

Также забыл закончить утверждение точкой с запятой, так что все равно 🙂

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

Здравствуйте,
отличный урок.
Даже я не смог найти путь к файлу. Я только что отладил приложение и попробовал это myExternalFile.getAbsolutePath(); & yipeee я нашел правильный путь к файлу.

Для меня это путь /storage/emulated/0/Android/data/имя вашего пакета/files/MyFileStorage/SampleFile.txt

Здравствуйте, отличное руководство, но вы рассмотрели только основное внешнее хранилище, а как насчет дополнительного?

спасибо, что поделились этим 😀

Как экспортировать данные, сохраненные в sqlite, в текстовый файл
Спасибо!

У меня также есть некоторые сомнения….

Невероятно раздражает, что всплывающее окно «БЕСПЛАТНАЯ электронная книга» закрывает часть дисплея, даже не показывая кнопку/поле «Закрыть». Будьте уверены, я никогда не куплю ничего, рекламируемого на этом веб-сайте, из-за htat.

Макет и параметры макета не связаны с java-файлом в приведенном выше коде.

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

привет, анупам,
мне нужна твоя помощь, если возможно.
У меня есть изображение с помощью веб-сервисов json.
Теперь мне нужно загрузить это, нажав кнопку загрузки и отобразив магазин в моем мобильном хранилище.
как я могу выполнить эту задачу.
ВЫ МОЖЕТЕ ОТВЕТИТЬ НА МОЮ ЭЛЕКТРОННУЮ ПОЧТУ .

Эй, у вас замечательный учебник, но я не могу найти файл, папка «MyFileStorage» пуста, но он все еще работает… Можете ли вы сказать мне, где я могу найти файл?

Хорошо, я понял, например. в SDCARD существует путь android/data/app_name/files/MyFileStorage, а папка пуста.

Android SDK, созданный для платформы x86, существует по пути android/data/имя_приложения/files/MyFileStorage/SampleFile.txt, но в чем разница? :/ А почему файл не на sdcard? 🙂

спасибо за ваше четкое объяснение и кодирование
-и вы заставили меня нервничать, когда я получил текст всплывающего уведомления:
«прочитано из внутренней памяти» (это опечатка)
ха: это все еще внешнее — я счастлив.
я хочу угостить тебя выпивкой!

Я не могу найти файл на своем устройстве. Можете ли вы сказать мне, где файл сохранен во внешнем хранилище на нашем устройстве?

Комментарии закрыты.

JournalDev — один из самых популярных веб-сайтов, посвященных Java, Python, Android и связанным с ними техническим статьям. Наши учебники регулярно обновляются, не содержат ошибок и полны. Каждый месяц миллионы таких же разработчиков, как и вы, посещают JournalDev, чтобы прочитать наши руководства.

JournalDev был основан Панкаджем Кумаром в 2010 году, чтобы поделиться своим опытом и знаниями со всем миром. Ему нравятся технологии с открытым исходным кодом, и писать в JournalDev стало его страстью.

Самые популярные

Избранные сайты

© 2021 · Политика конфиденциальности · Условия использования · Свяжитесь с нами · О нас · Часть JournalDev IT Services Private Limited

Я пытаюсь загрузить файл в Android 11, но не могу загрузить файл. Каждый раз, когда он выдает ENOENT: нет такого файла или каталога, откройте ошибку «/storage/emulated/0/fileName.pdf».

Текст был успешно обновлен, но возникли следующие ошибки:

xgenem прокомментировал 3 февраля 2021 г.

Яндамури прокомментировал 9 февраля 2021 г.

попробуйте получить разрешение следующим образом

предоставлено const = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);

Прокомментировал R4DIC4L 9 февраля 2021 г. •

Если вы хотите иметь возможность загрузить документ в хранилище Android, вы должны запросить у пользователя разрешение для PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE перед загрузкой и сохранением в хранилище, как указано @Yandamuri . Но если вы также хотите просмотреть/открыть документ для пользователя, вы также должны запросить разрешение пользователя PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE перед попыткой открыть его.

Для более старых версий Android необходимо добавить необходимые разрешения (см. ниже) в AndroidManifest.xml в теге манифеста перед тегом приложения. Они запрашиваются при установке приложения, а не при его использовании, и это также относится к другим разрешениям Android (Bluetooth, камера и т. д.).

Яндамури прокомментировал 13 февраля 2021 г.

@R4DIC4L Не могли бы вы сообщить нам, до какой версии разрешений Android необходимо указывать в Androidmanifest.xml?

Прокомментировал R4DIC4L 13 февраля 2021 г.

Я считаю хорошей практикой также включать разрешения в манифест, поскольку для Android 5.1 и более ранних версий это легко сделать и обрабатывать Play Store автоматически во время установки (вы получаете Granted при запросе кода по умолчанию, поскольку пользователь подтверждает все необходимые разрешения при согласии установить ваше приложение), разрешения также отображаются на странице приложения, когда вы нажимаете «Просмотреть разрешения на странице «О программе». Но вы можете пропустить это, если для установки приложения у ваших пользователей должна быть версия Android 6 и выше.

Прокомментировал R4DIC4L 13 февраля 2021 г. •

Поэтому вам, вероятно, также необходимо установить requestLegacyExternalStorage="true" в узле приложения в манифесте для использования старой модели хранилища также на Android 11. Дополнительные сведения см. в документации для разработчиков Android. В приведенной выше ссылке указано, что:
Значение по умолчанию: - false для приложений с targetSdkVersion >= 29 (Q). - верно для приложений с targetSdkVersion < 29.

i1990jain прокомментировал 19 февраля 2021 г.

эта установка устраняет ошибку загрузки файла на Android 10/11

Марф прокомментировал 15 апреля 2021 г.

Здравствуйте, поскольку с 5 мая Google Play будет игнорировать этот флаг и удалять приложения, которые не используют API, такие как Media Store или Storage Access Framework, что нам делать?

Яндамури прокомментировал 20 апреля 2021 г. •

@marf есть какие-нибудь официальные уведомления по этому поводу? если да, не могли бы вы отправить мне ссылку?

прокомментировал marf 20 апреля 2021 г.

Здравствуйте, @Yandamuri,
это ссылка: документы.

скоро будет проигнорировано, а также приложение, загруженное с включенным этим флагом, получит предупреждение от Google об этом факте.

cstehreem прокомментировал 25 апреля 2021 г.

Кто-нибудь нашел обходной путь для этой проблемы? Поскольку крайний срок 5 мая довольно близок..

rcerrejon прокомментировал 27 апреля 2021 г.

@marf
Для обновления из приложения я обнаружил обратную совместимость с legacyExternalStorage, но только для обновлений, а не для новых установок.
с флагом:

API 30 необходим для определения флага android:preserveLegacyExternalStorage.

прокомментировал marf 27 апреля 2021 г.

Проблема в том, что Google заявил, что после 5 мая этот флаг будет игнорироваться, поскольку его цель состояла только в том, чтобы помочь разработчикам в переходный период, который в настоящее время заканчивается.

Прокомментировал R4DIC4L 29 апреля 2021 г. •

Я вижу следующее уведомление в Google Play:

Разработчики приложений на устройствах под управлением Android 11+ должны использовать Scoped Storage, чтобы предоставить пользователям лучший контроль над доступом к хранилищу своих устройств. Чтобы выпустить свое приложение на Android 11 или более поздней версии после 5 мая, вы должны:

обновить свое приложение, чтобы использовать более безопасные методы обеспечения конфиденциальности, такие как Storage Access Framework или API Media Store
Обновить ваше приложение, чтобы объявить разрешение на доступ ко всем файлам (MANAGE_EXTERNAL_STORAGE) в файле манифеста и заполнить декларацию о разрешении на доступ ко всем файлам в Play Console с 5 мая.
Полностью удалите разрешение на доступ ко всем файлам из вашего приложения.
Для приложений, ориентированных на Android 11, флаг requestLegacyExternalStorage будет игнорироваться. Вы должны использовать разрешение на доступ ко всем файлам, чтобы сохранить широкий доступ.

Приложения, запрашивающие разрешение на доступ ко всем файлам без разрешенного использования, будут удалены из Google Play, и вы не сможете публиковать обновления. .

Насколько я понимаю, временный вариант, пока доступ к хранилищу не будет доступен в собственном пакете реакции, мы также можем объявить разрешение MANAGE_EXTERNAL_STORAGE в манифесте (у меня уже есть READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE), и оно будет действовать как разрешение для всех файлов. Это означает, что пользователь также должен будет дать явное разрешение приложению, управляющему их внешним хранилищем. Это, вероятно, необходимо запрашивать для более новых API вместе с двумя другими при попытке доступа к хранилищу.

Прокомментировал R4DIC4L 29 апреля 2021 г.

Кто-нибудь пытался загрузить новую сборку в Play Store (даже для внутреннего/бета-тестирования)? Я не уверен, что это действительно сработает.

guofoo прокомментировал 7 мая 2021 г.

прокомментировал gabrielporcher 20 мая 2021 г.

@R4DIC4L
На прошлой неделе я провел внутреннее тестирование, а сегодня провел бета-тестирование. В моем приложении используется targetSdkVersion 29, и я все еще использую android:requestLegacyExternalStorage="true". С магазином все в порядке, мое приложение все еще работает и появляется в магазине.

Но меня не устраивает эта новая стратегия хранения.

На данный момент кажется, что react-native-fs не работает без android:requestLegacyExternalStorage="true".

Прокомментировал R4DIC4L 20 мая 2021 г.

@gabrielporcher Я также использую целевой SDK 29 с android:requestLegacyExternalStorage="true" и могу подтвердить, что вы можете успешно загрузить приложение в Play Store. Тем не менее, они уведомили в Play Console, что после августа приложение должно будет ориентироваться на SDK 30, а android:requestLegacyExternalStorage="true" больше не будет работать, что заставит нас использовать новое хранилище с ограниченной областью действия.

Я также сбит с толку, так как я не полностью понимаю Scoped Storage и не думаю, что какие-либо реагирующие нативные пакеты готовы к этому изменению в данный момент.

enigmablue прокомментировал 3 июня 2021 г.

Я не могу отправить PDF-файл, несмотря на наличие android:requestLegacyExternalStorage="true" и WRITE_EXTERNAL_STORAGE/READ_EXTERNAL_STORAGE .

Выдает EACCES (отказано в доступе) при попытке прочитать его с помощью RNFS (но статистика работает) и не может загрузить его (сокет закрыт).

santiconte прокомментировал 20 июля 2021 г.

нашли какое-нибудь решение для сохранения файлов в android 11?

ashish-hiverhq прокомментировал 30 августа 2021 г.

Август почти закончился, есть новости по этой проблеме?

AdnanAhraf7 прокомментировал 1 сентября 2021 г.

android:requestLegacyExternalStorage="true"
Добавление этого в манифест Android помогло мне на Android 8,9,10,11

malgorzatatanska прокомментировала 1 сентября 2021 г.

tusharaddeveloper прокомментировал 4 сентября 2021 г. •

Добавить это разрешение в файл манифеста:

Используйте приведенный ниже код для сохранения файла. Нет необходимости разрешать какое-либо разрешение на хранение в > Q для того же:

smismmailalam прокомментировал 13 октября 2021 г.

Здравствуйте, есть новости по этому вопросу? Я также сталкиваюсь с той же проблемой в Android 11. Добавляю это в файл манифеста Android android:requestLegacyExternalStorage="true", но безуспешно

trungitvn прокомментировал 14 ноября 2021 г.

Всем привет! Есть ли какое-нибудь решение? - Надеюсь, кто-нибудь может помочь мне с этим, пожалуйста!

enigmablue прокомментировал 14 ноября 2021 г.

Я использую react-native-android-uri-path. Но я не знаю, решит ли это все ваши проблемы. Я в основном использую его для файлов content://, но я думаю, что он все еще работает.

импортировать getPath из '@flyerhq/react-native-android-uri-path';

и getPath на вашем пути, чтобы получить все абсолютные пути

trungitvn прокомментировал 15 ноября 2021 г.

Я нашел решение для себя. Надеюсь кому-нибудь помочь!

  • Чтобы скачать и сохранить файл для Android 11, я использую код:

nriccar прокомментировал 22 ноября 2021 г.

Я заметил такое же сообщение об ошибке, и оно не имело никакого отношения к разрешениям.

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

parameshwari5 прокомментировал 25 ноября 2021 г. •

вы можете использовать:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD_MR1) mPath= getActivity().getExternalFilesDir(Environment.DIRECTORY_DCIM) + "/" + now + ".jpg";
>
else
mPath= Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
>

niyasc прокомментировал 6 декабря 2021 г.

@parameshwari5 Конечно, это сработает. Но это не будет работать с версией 30, а для Google Play сейчас требуется, чтобы maxSdkVersion было равно 30.

dilantha111 прокомментировала 8 декабря 2021 г.

Привет, @trungitvn. Я получаю ту же ошибку для Android 10. Думаю, ваше решение может мне подойти, но я не совсем понимаю ваш код. Является ли DownloadManager другой библиотекой, которую вы используете? Очень признателен, если вы могли бы помочь. Спасибо

Shreyakkk прокомментировал 14 января 2022 г. •

Для Android 11 +
Попробуйте это
let dirPath = $/Documents/APP name
Не пытайтесь создать каталог приложения в корне. Используйте любую существующую папку, уже присутствующую в корне и создайте папку приложения внутри этой папки. В моем случае я создал внутри документов

Прокомментировал UVStudio 27 января 2022 г. •

@Shreyakkk Кажется, ваше решение работает для меня на Android 12. Спасибо.

EDIT: в течение дня я обнаружил, что если я удалю загруженный файл из файловой системы моего устройства, RNFS.ExternalStorageDirectoryPath или RNFS. DownloadDirectoryPath выдаст эту ошибку, если приложение снова попытается загрузить другой файл с тем же именем. Поэтому на данный момент я добавил Date.now() в toFile, чтобы убедиться, что каждый файл, загружаемый приложением, имеет другое имя (следовательно, другой путь).

Возможно, пока мой опыт недостаточно обширен, чтобы делать какие-либо окончательные выводы, но это действительно кажется странным.

У меня есть виджет с фоновым изображением из девяти патчей. Изображение было сохранено в /sdcard/mydir/bgs.

Когда я пытаюсь загрузить изображение с помощью метода setImageViewUri, возникает следующая ошибка:

Это появляется только на главном экране и только в Nexus 10 и Nexus 7 (в последней версии лаунчера 4.4 этой ошибки нет). У меня также есть несколько RemoteViews в моем приложении, и все работает правильно.

Я также добавил в манифест либо READ_EXTERNAL_STORAGE, либо WRITE_EXTERNAL_STORAGE.

Как решить?

ОБНОВЛЕНИЕ: я проверил метод setImageViewUri и обнаружил, что он изменяет путь к моему файлу.

Этот метод получает мое значение (/sdcard/mydir/bgs) и изменяет его на (storage/emulated/0/sdcard/mydir/bgs). Но этот файл не существует в системе через adb.

4 ответа 4

Как и в случае с Lollipop, Google представил новый способ явного предоставления приложениям разрешений, которые вы хотите, чтобы они использовали на вашем устройстве, и отключения тех приложений, которым вы хотите отказать. Если вы заметили, на вашем мониторе Android в журнале отображается

Отказ в разрешении EACCESS является причиной печально известного FileNotFoundException java.

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

введите здесь описание изображения

По умолчанию все разрешения отключены. Пользователь должен включать все каждый раз, когда вы устанавливаете приложение? Я никогда не делал этого на своем телефоне (версия 6.0.1).

в вашем манифесте.

Похоже, setImageViewUri больше небезопасно использовать с file:// uris.

Почему?

Компания Jellybean представила разрешение READ_EXTERNAL_STORAGE. Приложения, которые хотят читать из внешнего хранилища, должны иметь это разрешение. Это не применялось по умолчанию до KitKat.

У программы запуска нет этого разрешения. На самом деле вам не гарантируется, что любой RemoteView, к которому вы подключаетесь, имеет это разрешение. Это делает небезопасным использование setImageViewUri, поскольку вы не знаете, сможет ли удаленное представление изображения вообще прочитать данный uri.

Что теперь?

Вариант 1. Используйте setImageViewBitmap.

Возможно, вы отказались от этого варианта из-за неудачных транзакций связующего. Хитрость в том, что размер вашего изображения не должен превышать 1 МБ. Это не так сложно, как кажется. Вы можете точно рассчитать, насколько большим будет ваше изображение. Например, если вы используете изображение ARGB_8888, это означает, что вам потребуется 4 байта на пиксель. Мы можем рассчитать максимальный размер следующим образом:

1 МБ = 1048576 байт = 262144 пикселей = изображение размером 512 x 512

Конечно, вы можете выжать из него больше, используя RGB_565, чтобы получить вдвое больше пикселей.

Также обратите внимание, что вам может не понадобиться большое изображение, если ваш виджет маленький. Ваш виджет приложения может запрашивать конкретные параметры следующим образом:

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

Вариант 2. Используйте поставщика контента

Если по какой-то причине вам все еще не нравится ограничение IPC, вы всегда можете создать собственный поставщик контента. Передайте этот uri в setImageViewUri, и все готово.

Что насчет переключения пути?

Переключение пути не является реальной проблемой. Похоже, это проблема, но на самом деле эмуляция работает нормально. Попробуйте создать файл внутри //storage/emulated/0/sdcard/mydir/bgs, и файл будет создан нормально.

Вы заметите, что, несмотря на то, что исключение является FileNotFoundException, сообщение отказано в доступе.

мы используем react-native-fs для Android 11. У меня проблема: я больше не могу сохранять файлы Pfd и Excel в папке «Загрузки» (/storage/emulated/0/Download), потому что мы редактируем файлы через другие приложения, а затем снова загрузите файл в наше приложение. Я знаю, что с Android 11 доступ к хранилищу изменился, и это возможно только в так называемом хранилище области. Есть ли с react-native-fs или как-то иначе (через React Native) хранить файлы, чтобы другие приложения могли видеть файлы, или вы могли открывать их в проводнике Android или видеть их как общую папку для всех Программы. Существует также возможность с MANAGE_EXTERNAL_STORAGE, но этот параметр зарезервирован для определенных приложений только в соответствии с Android.

Нативная версия React: 64.2 react-native-fs: 2.18.0 Andriod 11

Заранее спасибо

Текст был успешно обновлен, но возникли следующие ошибки:

dincengincan прокомментировал 2 ноября 2021 г. •

Когда я запрашиваю разрешение, ничего не происходит. Я не вижу всплывающих окон или каких-либо уведомлений, думаю, обещание никогда не разрешается после выполнения запроса. Есть идеи? @gilsonviana-modus

Мой Android.manifest выглядит следующим образом:

комментарий iqbalprasas прокомментирован 3 ноября 2021 г.

Вам нужно добавить дополнительное разрешение MANAGE_EXTERNAL_STORAGE , вы можете увидеть в этом посте

прокомментировал ilyagru 15 ноября 2021 г.

abhishek-pokhriyal прокомментировал 27 ноября 2021 г.

MANAGE_EXTERNAL_STORAGE зарезервировано только для определенных типов приложений, и Google Play будет отклонять любые другие приложения, если у них есть это разрешение.

@ilyagru Ты прав. Разрешение очень сильное, и Google Play, похоже, очень осторожен с приложением, запрашивающим это разрешение. Есть ли обходной путь? Я получаю это при попытке сохранить изображение в память телефона:

WenLonG12345 прокомментировал 1 декабря 2021 г.

Привет @abhishek-pokhriyal, я попробовал ваше решение, но есть ошибка в RNFS.mkdir()
Ошибка

У меня Android 10. Есть идеи?

ilyagru прокомментировал 1 декабря 2021 г.

Моя проблема заключалась в том, чтобы загрузить и сохранить файл .pdf и открыть его с помощью средства просмотра по умолчанию на Android 11, как указано в первом сообщении в этой теме. Я исправил это несколькими вещами, и пока он работает как на Android 10, так и на 11 с моей стороны. копия @abhishek-pokhriyal

  1. Добавить в AndroidManifest.xml на том же уровне, что и разрешения (необходимо, чтобы иметь возможность открывать, например, файлы .pdf в средстве просмотра по умолчанию)
  1. Добавить корневой путь в android/app/src/main/res/xml/filepaths.xml
  1. Используйте RNFS.DocumentDirectoryPath на Android в качестве пути для загрузки документов.

abhishek-pokhriyal прокомментировал 1 декабря 2021 г. •

@WenLonG12345 Код, который я разместил, НЕ был решением. Это был просто код, который нормально работал, когда targetSdkVersion = 29. Как только я обновился до targetSdkVersion до 30, он перестал работать. Эта конкретная часть, которая перестала работать, была следующей:

Yoodley поддерживается читателями. Когда вы покупаете по ссылкам на нашем сайте, мы можем получать партнерскую комиссию.

Вы когда-нибудь пытались найти путь к файлу какого-либо изображения в своих файлах и находили путь к файлу, указывающий что-то вроде этого: «/storage/emulated/0/DCIM/Camera/IMG_202020430_197267.jpg»?

Теперь вы понимаете каждый аспект пути к файлу от DCIM к камере и имени изображения, но что означает ‘/storage/emulated/0’? Это должно вызвать у вас недоумение, потому что, когда вы пытаетесь отследить так называемую «эмулированную» папку в проводнике, в каталоге файлов ее нет.

Итак, вам, должно быть, интересно, что такое «/storage/emulated/0», и поскольку в каталоге с файлами под «эмулируемыми» нет конкретной папки, как вы можете получить к ней доступ? Это то, что мы подробно обсудим в этом посте.

Что такое /storage/emulated/0/ или эмулированное хранилище?

Android поддерживает различные типы устройств хранения данных, основными из которых являются портативные устройства хранения данных и эмулированные устройства хранения данных. В то время как портативное хранилище может быть предоставлено с помощью таких носителей, как USB или SD-карта, эмулируемое хранилище добавляется к устройству Android, позволяя открывать внутреннее хранилище через уровень эмуляции.

Эмуляция хранилища указывает расположение файла одного элемента по его символической ссылке на устройстве/внешнем хранилище.Символическая ссылка или символическая ссылка — это файл, который используется в качестве ссылки на другой файл или каталог, известный как «цель». Симлинк — это файл, который ОС интерпретирует напрямую как путь к «цели».

Например, если вы просматриваете путь к файлу изображения в папке DCIM, вы увидите путь к файлу, указанный как «/storage/emulated/0/DCIM/Camera», который является просто символической ссылкой на обычная папка DCIM/Camera (или целевая, в данном случае).

Вот еще один пример: если вы просматриваете элементы в каталоге Downloads/Music в папке с файлами, при просмотре пути к файлу определенного элемента вы увидите что-то вроде /storage/emulated/0/ Загрузки/Музыка/xyz.mp3. Хотя вы не открывали папку «/storage/emulated/0/», вы просматриваете только обычные загрузки/музыку; путь к файлу, на который вы смотрите, является символической ссылкой на каталог, также известный как эмулированное хранилище, на фактический каталог или цель, т. е. Downloads/Music.

Итак, /storage/emulated/0/ или эмулированное хранилище любого каталога — это не что иное, как ссылка на тот же каталог.

Почему ‘/storage/emulated/0/’ или эмуляция все равно существуют?

Вне зависимости от того, видите ли вы это или нет, в зависимости от используемого вами устройства Android эмуляция существует для всех файлов в папке с файлами. Единственная разница заключается в символической ссылке, которая видна на одних устройствах, а на других нет.

Почему же существует эмуляция? Предоставление уровня абстракции или эмуляции исходной файловой системы позволяет ограничить несанкционированный доступ сторонних приложений и систем к личным носителям пользователя и другим данным, лежащим в физических хранилищах, таких как SD-карты. Это означает, что эмуляция делает вашу фактическую файловую систему доступной только для просмотра и недоступной для чтения или записи сторонними приложениями/процессами в зависимости от разрешений.

Проще говоря, /storage/emulated/0/ или эмуляция — это один из подходов Android к повышению безопасности и конфиденциальности пользовательских данных.

Что такое /storage/emulated/1/?

Эмуляция может существовать как во внутренней, так и во внешней памяти; поэтому, чтобы различать их, Android может использовать 0 и 1 для обозначения каталога файла элемента, находится ли он во внутренней или внешней памяти, например на SD-карте.

Например, DCIM — это папка, которая может существовать как в памяти устройства, так и во внешнем хранилище. Теперь, если DCIM в обоих хранилищах (внутреннем и внешнем) имеет эмуляцию, он будет показывать /storage/emulated/0/DCIM для всех элементов, лежащих в папке DCIM внутреннего хранилища, и /storage/emulated/1/DCIM для всех элементов, которые хранятся в папке DCIM внешнего хранилища. 1 — это просто ссылка на внешнее хранилище, существующее на устройстве Android.

Как я могу получить доступ к /storage/emulated/0/ на устройстве Android?

Подключите ваше устройство и запустите оболочку adb, которая предоставит вам командную оболочку на вашем устройстве. У вас нет разрешения на чтение /storage/emulated/, но, поскольку вы знаете, что он находится в подкаталоге 0, просто перейдите cd /storage/emulated/0, и вы сможете осмотреться и взаимодействовать, как и ожидалось.

Самый простой способ получить доступ к /storage/emulated/0/ на устройстве Android — загрузить сторонний проводник, например ES File Explorer. Однако, скажем вам заранее, вы можете только осмотреть папку, и это почти все. Если вы откроете домашнюю страницу ES File Explorer и нажмете «Локальный», вы увидите папку с именем «эмулировать». Однако, если вы нажмете на папку, вы увидите сообщение «Пустая папка».

С другой стороны, если вы коснетесь внутреннего хранилища в ES, вы в конечном итоге будете перенаправлены в каталог, содержащий все папки во внутреннем хранилище. Если вы посмотрите на путь сверху, то увидите «/>storage>emulated>0». Если вы попытаетесь нажать «эмулировать» на пути, вы снова увидите «пустую папку».

Это просто означает, что /storage/emulated/0/ является корневым каталогом, и вы не можете получить к нему доступ. Доступ к папке с файлами во внутреннем или внешнем хранилище аналогичен доступу к /storage/emulated/0/; однако, если вы хотите получить к нему доступ, вы можете сделать это другим способом.

Подключите устройство к рабочему столу и запустите оболочку adb; поскольку Android не разрешает чтение /storage/emulated/0/, вы можете перейти в его подкаталог. Поскольку вы находитесь в своей командной оболочке (запустив оболочку adb), вы можете перейти к cd/storage/emulated/0 и посмотреть вокруг.

Что делать, если /storage/emulated/0/XYZ сообщает, что файл отсутствует или не читается, когда стороннее приложение пытается его прочитать?

Предположим, у вас есть приложение, которое ищет в определенном файле или папке элемент одной категории, например видео или музыку; он может искать то же самое в /storage/emulated/0/XYZ (где XYZ — любой подкаталог).Например, если у вас есть Poweramp для поиска музыки в папке /storage/emulated/0/Downloads, и если у вас нет музыки в той же папке, он покажет /storage/emulated/0/Downloads как отсутствующую или нечитаемую.< /p>

Ваше приложение может искать музыку в этом подкаталоге по двум причинам: во-первых, в ваших настройках было установлено музыкальное хранилище по умолчанию, или Poweramp ранее находил музыку в каталоге, который теперь удален. Теперь, чтобы решить эту проблему, все, что вам нужно сделать, это поместить музыку в папку /storage/emulated/0/Downloads, чтобы Poweramp мог искать воспроизведение для этой папки, или перейти в «Настройки»> «Poweramp»> «Библиотека»> «Загрузки» и снять флажок «Загрузки как». каталог, в котором приложение будет искать музыку.

Можно ли удалить эмулированную папку в Android?

Эмулированные папки ничем не отличаются от ваших исходных папок, в них хранятся все ваши данные, включая приложения, данные, загрузки, музыку и изображения. Поскольку фактический «эмулируемый» каталог доступен только для просмотра, но не для изменения или записи, вы можете удалить только свои исходные папки, чтобы удалить эмулированную папку на вашем Android.

Читайте также: