Как прочитать файл непосредственно из внешнего каталога загрузки на Android 10 (Q) - PullRequest
1 голос
/ 25 марта 2020

Я пытаюсь прочитать файл из папки загрузки на Android Q, выполнив следующее:

        File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
        File f = new File(downloadDir, "some-existing-file");
        if(!f.exists()) {
            throw new IllegalStateException();
        }

        Uri furi = Uri.fromFile(f);
        try {
            ParcelFileDescriptor des = getContentResolver().openFileDescriptor(
                    furi, "r", null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

Я также установил android:requestLegacyExternalStorage="true" в манифесте и запросил WRITE_EXTERNAL_STORAGE и READ_EXTERNAL_STORAGE разрешения времени выполнения.

Файл существует, но при попытке открыть дескриптор файла возникает исключение: java.io.FileNotFoundException: open failed: EACCES (Permission denied).

Я прочитал изменения, сделанные в Android Q хранилище, но не мог понять, как я могу просто прочитать файл без взаимодействия с пользователем.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 26 марта 2020

Этот метод устарел в Уровень API 29 . Для улучшения конфиденциальности пользователей прямой доступ к общим / внешним устройствам хранения данных не рекомендуется. Когда приложение предназначено для Build.VERSION_CODES.Q , путь, возвращаемый этим методом, больше не доступен напрямую для приложений. Приложения могут продолжать получать доступ к содержимому, хранящемуся в общем / внешнем хранилище, путем перехода на другие альтернативы, такие как Context # getExternalFilesDir (String) , MediaStore или Intent # ACTION_OPEN_DOCUMENT .

Скопировано из Android документов. Документы

0 голосов
/ 27 марта 2020

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

Я добавил в манифест:

android:requestLegacyExternalStorage="true"

При перестройке и переустановке непосредственно из Android Studio система сборки или android среда выполнения не регистрирует изменения в манифесте, и запрос на requestLegacyExternalStorage не регистрируется.

Я исправил его, полностью удалив приложение: adb uninstall com.example.app и снова установив его из android studio.

0 голосов
/ 25 марта 2020

С Android 6 (Зефир) некоторые из критических разрешений должны быть предоставлены пользователем во время выполнения, чтобы он / она знал, к чему может обращаться ваше приложение.
эта ссылка - это все, что вам нужно

РЕДАКТИРОВАТЬ
добавить их в манифест

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


, а затем добавить этот код в свой метод создания

if (android.os.Build.VERSION.SDK_INT >= 23 && (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
                PackageManager.PERMISSION_GRANTED)) {
            ActivityCompat.requestPermissions(
                    this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    2000);
        }


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

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == 2000) {
        //do what you want with files
    }
}


просто обратите внимание, что я установил код запроса на 2000. Это необязательно.

...