Ошибка разрешения пользователя Android M - ПРОЧИТАЙТЕ и ПИШИТЕ
Я только начал с Android M, и я не могу получить доступ к внешней памяти. Я получаю следующую ошибку
Caused by: java.lang.SecurityException: Permission Denial: reading
com.android.providers.media.MediaProvider uri
content://media/external/images/media from pid=15355, uid=10053 requires
android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
Я добавляю пользовательское разрешение в манифест как
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
и мой файл сборки со следующими настройками:
compileSdkVersion 23
buildToolsVersion "22.0.1"
minSdkVersion 16
targetSdkVersion 23
Как читать и писать с внешнего хранилища в Android M?
5 ответов
Чтение из документации. Я должен запросить у пользователя разрешение во время выполнения. Пример кода:
Добавьте разрешение для Android манифеста, как мы делали раньше:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Проверьте, предоставил ли пользователь разрешение. Если да, пропустите запрос на разрешение и продолжите работу, иначе попросите разрешения у пользователя:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(this)) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 2909);
} else {
// continue with your code
}
} else {
// continue with your code
}
Теперь, чтобы проверить, предоставил ли пользователь разрешение или отклонил его @Override
OnRequestPermissionResult
чтобы получить обратный звонок:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 2909: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("Permission", "Granted");
} else {
Log.e("Permission", "Denied");
}
return;
}
}
}
Я не смог ПРОЧИТАТЬ внешнее хранилище только запросив разрешение WRITE, поэтому мне пришлось запросить
Manifest.permission.READ_EXTERNAL_STORAGE
также.
Также, если вы хотите настроить таргетинг на версии ниже API 23, проверьте версию сборки во время выполнения с
IF
Заявление и запросить разрешения, только если VERSION равен или вышеAndroid M
,
Если вы ищете способ справиться с любой версией Android (вы компилируете для M, но некоторые устройства могут использовать другие версии), есть версия совместимости.
if (ContextCompat.checkSelfPermission(CreatePlayerActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(CreatePlayerActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(CreatePlayerActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
Что касается выбранного ответа:
Settings.System.canWrite(this)
а также WRITE_EXTERNAL_STORAGE
это две разные вещи! Должно быть:
boolean needsRead = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED;
boolean needsWrite = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED;
if (needsRead || needsWrite)
requestStoragePermission()
Я боролся с WRITE_EXTERNAL_STORAGE
разрешение: после того, как я просил это, диалог не показывался и немедленно возвращался DENIED
,
Проблема была в одной из включенных библиотек. Он содержал такую же декларацию разрешения в своем AndroidManifest.xml
, но с maxSdkVersion="22"
, Объявление в файле манифеста приложения было переопределено библиотекой.
Чтобы переопределить разрешение из библиотеки, я использовал следующее:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:node="remove"
tools:selector="com.example.lib" />
Я надеюсь, что это может быть полезно.
Я использовал эту утилиту на GitHub. Он работает с API 22 и 23. Добавление разрешений во время выполнения не сложно, но немного отделить ваш код и переместить методы для захвата обратных вызовов. Эта библиотека предоставляет связанный API для того, чтобы делать все, что вам нужно для поддержки разрешений во время выполнения.