Java.io.FileNotFoundException (permiso denegado) Al intentar escribir en el sdcard de Android

Estoy tratando de seleccionar un archivo de imagen de la galería de fotos y escribir en la tarjeta SD. A continuación se muestra el código que resulta en una excepción. Parece lanzar esta excepción al intentar crear el FileOutputStream. Tengo la línea siguiente agregada al archivo de manifiesto anidado dentro del elemento de la aplicación. No puedo encontrar una solución al problema:

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

 public boolean saveSelectedImage( Uri selectedImage, int imageGroup, int imageNumber ) { boolean exception = false; InputStream input = null; OutputStream output = null; if( externalStorageIsWritable() ) { try { ContentResolver content = ctx.getContentResolver(); input = content.openInputStream( selectedImage ); if(input != null) Log.v( CLASS_NAME, "Input Stream Opened successfully"); File outFile = null; File root = Environment.getExternalStorageDirectory( ); if(root == null) Log.v(CLASS_NAME, "FAILED TO RETRIEVE DIRECTORY"); else Log.v(CLASS_NAME, "ROOT DIRECTORY is:"+root.toString()); output = new FileOutputStream( root+"/Image"+ imageGroup + "_" + imageNumber + ".png" ); if(output != null) Log.e( CLASS_NAME, "Output Stream Opened successfully"); // output = new FileOutputStream // ("/sdcard/Image"+imageGroup+"_"+imageNumber+".png"); byte[] buffer = new byte[1000]; int bytesRead = 0; while ( ( bytesRead = input.read( buffer, 0, buffer.length ) ) >= 0 ) { output.write( buffer, 0, buffer.length ); } } catch ( Exception e ) { Log.e( CLASS_NAME, "Exception occurred while moving image: "); e.printStackTrace(); exception = true; } finally { // if(input != null)input.close(); // if(output != null)output.close(); // if (exception ) return false; } return true; } else return false; } 

Así es como debe ser su archivo de manifiesto

 <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".WriteCBTextToFileActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

Tuve este problema y las respuestas aquí no lo arreglaron, porque había cometido un error bastante tonto.

Asegúrese de darle a su emulador de Android una tarjeta SD … Había dejado el tamaño de la tarjeta SD en blanco y por supuesto, no pudo encontrar nada. Encima de eso, estaba especificando un directorio dentro de dicha tarjeta SD que aún no había sido creado así que asegúrese de considerar ese caso también.

(Puede cambiar la configuración de la tarjeta SD de un AVD accediendo al Administrador de dispositivos virtuales de Android, editando el emulador de su elección e ingresando algún valor para el tamaño de la tarjeta SD)

También debe asegurarse de que el subsistema de almacenamiento externo está en el estado correcto; Use Environment.getExternalStorageState() y busque Environment.MEDIA_MOUNTED que es el único estado seguro.

También es una buena idea restringir el manejo de excepciones a IOException torno a esas secciones, por lo que no se sobre-recuperará de problemas específicos de IO, por ejemplo, medios desmontados.

Si necesita eventos, hay intenciones de difusión ( Intent.ACTION_MEDIA_xxx ) con la misma información que puede registrar con IntentListener .

También tenga en cuenta que el almacenamiento externo puede estar deshabilitado cuando está usando USB para depurar!

También hay un período prolongado durante el inicio del dispositivo, donde el almacenamiento externo no está disponible. Si haces cosas en los servicios en el inicio, este es un problema.

En general, su aplicación debe tener en cuenta el estado de almacenamiento externo cuando accede a él y manejar los casos en los que no está disponible o no está disponible mientras accede a ella.

Si tiene los permisos correctos establecidos en el manifiesto, asegúrese de que su dispositivo no está en el modo "Unidad de disco" cuando se conecta a un PC. Cambiarlo al modo "Cargar solamente" y debería funcionar.

Tenga en cuenta que además de la respuesta de Saurabh, ya que la API 23 necesita solicitar permisos en tiempo de ejecución.

Vea aquí: https://developer.android.com/training/permissions/requesting.html

Y la respuesta de Justin Fiedler aquí: https://stackoverflow.com/a/33288986/328059

Además, he tenido varios casos en los que después de cambiar el permiso y volver a ejecutar la aplicación con Instant Run, los permisos no se actualizaron. Por lo tanto, como una mejor práctica, después de cambiar el manifiesto, desinstalo la aplicación del dispositivo de destino y reconstruir.

Puede probar con:

 String myPath=Environment.getExternalStorageDirectory()+"/Image"+ imageGroup + "_" + imageNumber + ".png"; File myFile = new File(); input = new FileInputStream(myFile); 

Trate de utilizar openFileOutput("filename") para devolver un FileOutputStream en lugar de especificar la ubicación por usted mismo.

Revise el documento aquí

  • Cómo escanear la tarjeta SD para la extensión particular de los archivos en android?
  • Abrir el selector de archivos de mi actividad de Android
  • Android: Error al entregar el resultado ResultInfo {who = null, request = 1, result = -1, data = Intent
  • Abrir un archivo de texto de 12kb toma WAY demasiado tiempo ...?
  • FileNotFoundException + Escribir un archivo en la tarjeta SD
  • ACTION_GET_CONTENT: ¿Cómo obtener el fin del archivo al buscar varios tipos de archivo?
  • Poner manualmente archivos en la tarjeta SD del emulador de Android
  • ¿Cómo implementar SD Card Gallery sin personalización en android?
  • Cómo abrir un archivo PDF local en PhoneGap (android)
  • Error al empujar el elemento (s). En android
  • Transmita la salida logcat de android a una tarjeta sd
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.