Android 11 - Доступ к файлам в моем приложении Android/ Папка данных
По какой-то причине я действительно борюсь с этим и надеюсь, что кто-то может помочь мне указать правильное направление.
Я нацелен на Android 11 / API 30, и, похоже, именно отсюда и возникла проблема. Более низкий таргетинг может сработать для меня, но похоже, что Google в конечном итоге заставит меня пойти по этому пути, так что я мог бы просто понять это.
Мои приложения обычно записывают файлы в стандартный
getExternalFilesDir(null)
Это дает мне путь к устройству, которое
/storage/emulated/0/Android/data/com.domain.testapp/files
Я также пробовал другие типы, например:
getExternalFilesDir(Environment.DIRECTORY_PICTURES)
приводит к
/storage/emulated/0/Android/data/com.domain.testapp/files/Documents
У моего приложения нет проблем с записью файлов в это место. В Android 11 мне нужно перепрыгнуть через несколько обручей с локальным файловым проводником, чтобы увидеть эти файлы, но они действительно существуют на устройстве.
Теперь я пытаюсь дать пользователю возможность видеть файлы и делиться ими, и вот где я в тупике!
Этот код ниже приводит к тому, что файлы не найдены
File filePath = this.getExternalFilesDir(null);
String filePathString = filePath.toString();
ArrayList<String> myData = new ArrayList<>();
File fileDir = new File(filePathString);
String[] files = fileDir.list();
if(files.length == 0){
Log.w(APPID, "NO FILES IN FOLDER");
}
Да, я знаю, что File и .toString() не нужны, но я выводил их из системы на каждом шаге, потому что думал, что сошел с ума.
Я точно знаю, что в папке, на которую он указывает в этом приложении, находится около дюжины файлов. Это приложение создало файлы. Разве он не должен видеть файлы в папке ???
У манифеста есть следующие разрешения, которые, как мне кажется, не нужны ему полностью:
<uses-permission android:name = "android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
Никакие разрешения не отображаются как отклоненные для приложения
Я думал об использовании внешнего хранилища - но кажется, в Android 11 это еще сложнее? Или это действительно более легкий путь?
Я пробовал поиграть с этим, но кажется, что он устарел и скоро исчезнет?
File downloadFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
что это за папка на моем устройстве
/storage/emulated/0/Download
И я определенно могу увидеть файлы там с помощью любого файлового проводника.
Есть мысли о том, как получить доступ к файлам, созданным этим приложением?
Я, наверное, упускаю что-то действительно очевидное.
Любые предложения приветствуются !!
6 ответов
Думаю, у меня есть ответ?
Чем больше я читаю об этом - похоже, что Android 10 пошёл в одну сторону, а затем Android 11 немного отследил его и повторно разрешил прямой доступ к некоторым путям к файлам.
Надеюсь, я прав в этом, и мне не придется возвращаться и переделывать вещи снова в будущем
Итак, ответ - использовать requestLegacyExternalStorage в манифесте, даже если у него есть всевозможные предупреждения.
И затем я создал папку в Документах с этим
File filePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)+File.separator+"MyAppFolder");
filePath.mkdirs();
И теперь я могу писать туда и читать.
В любом случае - похоже, это работает для меня на Android 9, 10 и 11. Так что, надеюсь, тенденция вперед сохраняется.
Google Play Store требует, чтобы вы использовали ОБЪЕМНОЕ ХРАНИЛИЩЕ, а не ОБЩЕЕ ХРАНИЛИЩЕ, поэтому вам следует избегать использования "requestLegacyStorage".
Это означает, что вы не можете получить доступ к файлам на SD-карте, если пользователь не выбрал их напрямую. Чтобы выбрать файл из внешнего хранилища, вам потребуется взаимодействие с пользователем (:
Есть еще одно решение с Android>= 10, и это разрешение «MANAGE_EXTERNAL_STORAGE», которое позволяет вам выбрать приложение, которое может получить доступ к внешнему хранилищу. Но пользователь должен выполнять все действия, поэтому это не совсем хорошее решение:/
Если ваша проблема связана с файлами, которые вы делаете во внешнем хранилище при взаимодействии с пользователем, вы можете включить доступ к uri файла с помощью fileProvider (из примера, когда вы делаете фотографию).
Хорошего дня и приятного кодирования (:
Добавьте строку ниже в файл манифеста Android в теге приложения.
android:requestLegacyExternalStorage="true"
Для Android 11 и выше Используйте это перед запросом
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
Чтобы просмотреть и сохранить:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+"/FolderName/"+new_filename+"/");
File[] allfiles = null;
allfiles = file.listFiles();
Log.i(TAG, String.valueOf(allfiles.length));
У вас есть следующее разрешение в вашем манифесте? Вы говорите, что у вас есть разрешение на запись и управление, но я думаю, что вам действительно требуется разрешение на чтение для чтения внешнего хранилища.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
пожалуйста, опишите ваш вопрос правильно
если вы хотите забрать файл из внешнего хранилища, также примените в манифесте запрос legegyexternalstorage=true
смотрите в этих снимках - http://prntscr.com/114kqxp
или если вы хотите сохранить файл на устройстве, вам нужно использовать провайдер файлов в android
для примера с файловым провайдером
пожалуйста, посетите ссылку - не удалось прикрепить файл отправить электронное письмо android 11