listFiles() возвращает null в /storage/emulated, в то время как /storage/emulated/0 существует

Я тестирую эмулятор Android 27 и пытаюсь пройти по некоторым каталогам.

Когда я пытаюсь просмотреть каталог /storage/emulated, метод listFiles() возвращает null, в то время как существует /storage/emulated/0.

Вот код тестирования:

File emuDir = new File("/storage/emulated");
File[] emuDirFiles = emuDir.listFiles(); // returns null.

File exStorageDir = new File("/storage/emulated/0")
exStorageDir.exists(); // returns true

P.S. Я добавил правильное разрешение на хранение в манифест и предоставил разрешение во время выполнения.


person amirz98    schedule 07.09.2019    source источник


Ответы (3)


Короткий ответ: Android не предоставит вашему приложению разрешение на доступ к /storage/emulated.

Подробный ответ и причина, по которой ваше решение не работает:

Какие разрешения вы предоставили? Я предполагаю, что это EXTERNAL_WRITE/EXTERNAL_READ, и они дадут вам доступ к /storage/emulated/0, который является тем же каталогом, который возвращает getExternalStorageDirectory(). Android не дает разрешения на чтение/запись для /storage/emulated. В качестве примечания: если File.canRead() возвращает false, вы не можете listFiles() этого каталога. В вашем случае, даже если вы добавили разрешения, emuDir.canRead() вернет false, потому что эти разрешения предоставляют доступ к /storage/emulated/0, а не к /storage/emulated

person Farid    schedule 07.09.2019
comment
Я предоставил как android.permission.WRITE_EXTERNAL_STORAGE, так и android.permission.READ_EXTERNAL_STORAGE. Также проверил метод canRead() на /storage/emulated, возвращает false. Мне интересно, почему это происходит, потому что я могу просматривать системные каталоги, например, каталог /proc и другие. - person amirz98; 07.09.2019
comment
Если он возвращает false, вы ничего не можете сделать. Каталог Android /system доступен для чтения (canRead() возвращает true), поэтому вы можете перечислить файлы в этом каталоге. Но /storage/emulated не читается, если вы не рутируете свое устройство. - person Farid; 07.09.2019
comment
К сожалению, у Android нет категории разрешений для доступа к этому каталогу, независимо от того, какое разрешение вы добавляете. - person Farid; 07.09.2019
comment
Могу я спросить, почему вы пытаетесь получить доступ к этому каталогу, просто из любопытства. Можете не отвечать, если это личное )). Я могу предложить альтернативу, если что-то придет мне в голову. - person Farid; 07.09.2019
comment
Я просматриваю все каталоги, начиная с /, в этом случае он не сможет пройти /storage/emulated! У вас есть какие-либо предложения? - person amirz98; 07.09.2019
comment
Если вы рутируете свое устройство, вы можете использовать su/sudo. Но у меня нет личного опыта работы с этими командами. Я мог бы помочь вам, но я не хочу рутировать свое устройство. Вы можете проверить этот вопрос stackoverflow.com/q/27274339/5636313 в качестве отправной точки. - person Farid; 07.09.2019
comment
Спасибо, я думаю, что это принятый ответ. Однако это немного сбивает с толку, что он недоступен таким образом. - person amirz98; 08.09.2019

Это связано с Scoped Storage. Чтобы решить эту проблему, напишите

 android:requestLegacyExternalStorage="true"

в теге приложения файла манифеста, как показано ниже.

решение

Для получения дополнительной информации: https://medium.com/@pednekarshashank33/android-10s-scoped-storage-image-picker-gallery-camera-d3dcca427bbf

person Salman Khalid    schedule 06.08.2020
comment
Спасибо, это помогло мне. Имейте в виду, что это исправление не будет работать, если оно нацелено на Android 11+. - person user1103538; 03.01.2021

После успешного запроса разрешения. Добавьте эту строку:

android:requestLegacyExternalStorage="true"

для области применения в AndroidManifest.xml

person Nam Vu Hoai    schedule 12.07.2021
comment
стоит отметить: medium.com/androiddevelopers/scope-storage-myths-ca6a97d7ff37 - person mochadwi; 12.07.2021