Ошибка открытия Android 6.0: EACCES (отказано в разрешении)
Я добавил uses-permission
including WRITE_EXTERNAL_STORAGE
, MOUNT_UNMOUNT_FILESYSTEMS
READ_EXTERNAL_STORAGE
AndroidManifest.xml
к,,.
Когда я попытался запустить свое приложение в Nexus5 (Android 6.0), оно выдало исключение, как показано ниже:
java.io.IOException: open failed: EACCES (Permission denied)
И я попробовал другой телефон Android (Android 5.1), все было в порядке.Вот код:
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
currentPhotoPath = image.getAbsolutePath();
return image;
}
Есть ли разница в разрешениях для Android 6.0?
Переведено автоматически
Ответ 1
Android добавил новую модель разрешений для Android 6.0 (Marshmallow).
Итак, вы должны проверить Runtime Permission
:
Что такое разрешения во время выполнения?
В Android 6.0 Marshmallow Google представила новую модель разрешений, которая позволяет пользователям лучше понимать, почему приложение может запрашивать определенные разрешения. Вместо того, чтобы пользователь слепо принимал все разрешения во время установки, пользователю теперь предлагается принимать разрешения по мере их возникновения в процессе использования приложения.
Когда внедрять новую модель?
полной поддержки не требуется, пока вы не выберете в своем приложении версию 23. Если вы ориентируетесь на версию 22 или ниже, ваше приложение запросит все разрешения во время установки точно так же, как это было бы на любом устройстве, работающем под управлением ОС ниже Marshmallow.
Эта информация взята отсюда :
Пожалуйста, проверьте, как реализовать, по этой ссылке :
Ответ 2
В Android 6 (Marshmallow), даже если пользователь принял все ваши разрешения во время установки, позже он может решить отобрать у вас некоторые из этих разрешений.
Быстрое решение, но не рекомендуется: возможно, если вы измените свой targetSdkVersion
в gradle на 22
, проблема будет решена.
Как реализовать?(Рекомендации)
Сначала определите, является ли устройство пользователя устройством Marshmallow или нет:
private boolean shouldAskPermission(){
return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1);
}Если
shouldAskPermission()
вернетесьtrue
, запросите необходимое разрешение:String[] perms = {"android.permission.WRITE_EXTERNAL_STORAGE"};
int permsRequestCode = 200;
requestPermissions(perms, permsRequestCode);
Метод requestPermissions(String[] permissions, int requestCode);
является открытым методом, находящимся внутри класса Android Activity.
Вы получите результаты вашего запроса в методе onRequestPermissionResult, как показано ниже:
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case 200:
boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
break;
}
}
После получения результатов вам нужно будет обработать их соответствующим образом.
Рекомендуемый поток разрешений:
Подробная информация:
Пользователь с устройством Marshmallow теперь будет иметь возможность отозвать опасные разрешения через настройки приложения
Android определяет некоторые разрешения как “опасные”, а некоторые - как “обычные". Оба разрешения требуются в манифесте вашего приложения, но только для опасных разрешений требуется запрос среды выполнения.
Если вы решили не внедрять новую модель разрешений (запрос во время выполнения), отзыв разрешений может вызвать нежелательный пользовательский опыт и, в некоторых случаях, сбой приложения.
В таблице ниже перечислены все текущие опасные разрешения и их соответствующие группы:
Если пользователь принимает одно разрешение в группе / категории, он принимает всю группу!
Источник:http://www.captechconsulting.com
Использование библиотеки Dexter:
Вы можете использовать Dexter. Библиотека Android, упрощающая процесс запроса разрешений во время выполнения.
Ответ 3
Вы также можете использовать ActivityCompat.requestPermissions для обратной совместимости.
пример:
private static final int REQUEST_CODE = 0x11;
String[] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE"};
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE); // without sdk version check
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// save file
} else {
Toast.makeText(getApplicationContext(), "PERMISSION_DENIED", Toast.LENGTH_SHORT).show();
}
}
}
Ответ 4
Из API-23 вам необходимо объявить разрешение в activity, даже если вы уже объявили в манифесте.
// Storage Permissions variables
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
//persmission method.
public static void verifyStoragePermissions(Activity activity) {
// Check if we have read or write permission
int writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
if (writePermission != PackageManager.PERMISSION_GRANTED || readPermission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
Чтобы использовать simply call verifyStoragePermissions(this);
в onCreate.
Надеюсь, это сработает.