Error de Android 6.0 abierto: EACCES (Permiso denegado)

He agregado uses-permission WRITE_EXTERNAL_STORAGE , incluidos WRITE_EXTERNAL_STORAGE , MOUNT_UNMOUNT_FILESYSTEMS , READ_EXTERNAL_STORAGE a AndroidManifest.xml .

Cuando traté de ejecutar mi aplicación en Nexus5 (Android 6.0), arrojó una excepción como la siguiente:

java.io.IOException: open failed: EACCES (Permission denied)

Y probé otro teléfono Android (Android 5.1), todo estaba bien. Aquí está el código:

 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; } 

¿Tiene Android 6.0 diferencia sobre el permiso?

Android agregó un nuevo modelo de permiso para Android 6.0 (Marshmallow) .

http://www.captechconsulting.com/blogs/runtime-permissions-best-practices-and-how-to-gracefully-handle-permission-removal

Entonces debes verificar el Runtime Permission :

¿Qué son los permisos de tiempo de ejecución?

Con Android 6.0 Marshmallow, Google presentó un nuevo modelo de permiso que permite a los usuarios comprender mejor por qué una aplicación puede estar solicitando permisos específicos. En lugar de que el usuario acepte ciegamente todos los permisos en el momento de la instalación, ahora se le solicita al usuario que acepte los permisos a medida que sean necesarios durante el uso de la aplicación.

¿Cuándo implementar el nuevo modelo?

no requiere soporte completo hasta que elija apuntar a la versión 23 en su aplicación. Si su objective es la versión 22 o inferior, su aplicación solicitará todos los permisos en el momento de la instalación como lo haría en cualquier dispositivo que ejecute un sistema operativo debajo de Marshmallow.

Esta información está tomada desde aquí:

Por favor, compruebe cómo implementar desde este enlace:

http://www.captechconsulting.com/blogs/runtime-permissions-best-practices-and-how-to-gracefully-handle-permission-removal

En Android 6 (Marshmallow) , aunque el usuario aceptó todos sus permisos en el momento de la instalación, luego puede decidir quitarle algunos de esos permisos.

Solución rápida pero no recomendada: quizás si cambia su targetSdkVersion en el gradle a 22 , el problema será resuelto.

¿Cómo implementar? (Mejores prácticas)

  1. Primero determine si el dispositivo del usuario es un dispositivo Marshmallow o no:

     private boolean shouldAskPermission(){ return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1); } 
  2. Si shouldAskPermission() devuelve true , solicite permiso que necesita:

     String[] perms = {"android.permission.WRITE_EXTERNAL_STORAGE"}; int permsRequestCode = 200; requestPermissions(perms, permsRequestCode); 

El método requestPermissions(String[] permissions, int requestCode); es un método público que se encuentra dentro de la clase de actividad de Android.

  1. Recibirá los resultados de su solicitud en el método onRequestPermissionResult como se muestra a continuación:

     @Override public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){ switch(permsRequestCode){ case 200: boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED; break; } } 

Después de recibir los resultados, deberá manejarlos adecuadamente.

Flujo de permisos sugeridos:

enter image description here

Más información:

Un usuario con un dispositivo Marshmallow ahora tendrá la capacidad de revocar permisos peligrosos a través de la configuración de la aplicación

Android define algunos permisos como ” peligrosos ” y algunos permisos como ” normales “. Ambos son obligatorios en el manifiesto de su aplicación, pero solo los permisos peligrosos requieren una solicitud en tiempo de ejecución.

Si ha elegido no implementar el nuevo modelo de permisos (solicitud de tiempo de ejecución), la revocación de permisos puede causar experiencias de usuario no deseadas y, en algunos casos, fallos de la aplicación.

La siguiente tabla enumera todos los permisos peligrosos actuales y sus respectivos grupos:

enter image description here

Si el usuario acepta un permiso en un grupo / categoría, ¡acepta a todo el grupo!

Fuente: http://www.captechconsulting.com

Usando la Biblioteca de Dexter:

Puedes usar Dexter . Biblioteca de Android que simplifica el proceso de solicitud de permisos en tiempo de ejecución.

También puede usar ActivityCompat.requestPermissions para compatibilidad con versiones anteriores.

ejemplo:

 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(); } } } 

Desde API-23 necesita declarar el permiso en actividad incluso si ya ha declarado en manifiesto.

 // 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 ); } } 

Para usar simplemente llame verifyStoragePermissions(this); en onCreate. Eso debería hacerlo con suerte.

Si eres perezoso, solo baja la versión de targetSdkVersion a 22 (antes de piruleta)

Esto funcionó para mí.

Vaya a Configuración -> Aplicaciones -> YourApp -> Proporcione permisos a Almacenamiento, Contactos, etc.

Para mí, mi teléfono conectado como USB como MTP fue el problema, incluso después de hacer todo lo que se indica aquí. Lo cambié a “Carga solo” funcionó para mí.

Me encontré con el mismo problema.

Tal vez sea causado por el mecanismo de seguridad de tu teléfono. Puede ir a ‘configuración’ para autorizar permisos de escritura / lectura.