API 26+: разрешение WRITE_EXTERNAL_STORAGE всегда отрицается

Я переключил свое приложение для целевой API 27, и теперь она не может быть предоставлено WRITE_EXTERNAL_STORAGE разрешения - grantResult всегда -1.

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

Я знаю, что в API 26 были изменения поведения для разрешений. Однако это не объясняет мою проблему.

Я запрашиваю как READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE разрешения стандартным образом:

ActivityCompat.requestPermissions(activity, new String[] {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    }, requestCode);

(оба разрешения объявляются через <uses-permission в манифесте).

Появится диалоговое окно, и я нажимаю "Разрешить":

enter image description here

Однако внутри обратного вызова onRequestPermissionsResult я получаю -1 (отклонено) для WRITE_EXTERNAL_STORAGE0 (предоставлено) для READ_EXTERNAL_STORAGE).

Разве не должен быть 0 для обоих, поскольку я попросил и, предположительно, предоставил оба?

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

Еще одна деталь: я только что проверил объединенный манифест в build/intermediates/manifests/full/debug и заметил, что разрешение WRITE_EXTERNAL_STORAGE имеет атрибут android:maxSdkVersion="18" (в моем манифесте нет такого атрибута). Это может произойти, потому что у моего приложения есть minApiVersion=21, но я не уверен.

Ответ 1

Где-то вдоль линии вы подбираете этот android:maxSdkVersion="18". Я предполагаю, что это происходит из библиотеки. Проверьте вкладку "Объединенный манифест" в Android Studio, когда вы редактируете свой собственный манифест. Он будет содержать детали того, что способствует различным элементам и атрибутам.

android:maxSdkVersion приводит к удалению элемента <uses-permission> в более высоких версиях Android SDK, по крайней мере, с точки зрения того, как работают разрешения времени выполнения.

Так как вам нужно это разрешение для всех версий, добавление tools:remove="android:maxSdkVersion" <uses-permission> должно вернуть android:maxSdkVersion="18" и дать вам то, что вы ожидаете.

Ответ 2

У меня есть приложение Android, которое использует данные (чтение/запись) на SD-карте. Итак, я сделал мастер этой карты и дублирую ее дубликатором.

Я провел несколько тестов и думаю, что могу сказать, что SD-карта от мастера SD, отформатированного в Android 8, работает (чтение/запись) со всеми нисходящими версиями Android (7 и 6) и Android 8, конечно. С другой стороны, SD от мастера SD-карты, отформатированной в Android 7, не работает под Android 8. Единственный вариант - отформатировать SD.

Знаете ли вы, что происходит при форматировании SD-карты под Android 8, чтобы произвести такое поведение?