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" />
- (Re) montaje de la tarjeta SD en el emulador de Android
- creando un drawable de la tarjeta del SD para fijar como fondo en android
- Android FileProvider para ext sdcard
- Necesita ayuda para emular el Samsung Galaxy Nexus con AVD
- Cómo leer un archivo de texto seleccionado de sdcard en android
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; }
- ¿Cómo comprobar el permiso se concede para una ruta de directorio y no abre el error EACCES?
- Android: Guardar el archivo permanentemente (incluso después de borrar datos / desinstalar)
- Android intención para sdcard listo
- Cómo obtener Galley Thumbnail para la carpeta de imágenes en particular en android?
- Android External App Install (en la tarjeta SD), vuelva a cargar las alarmas del alarmmanager al re-montar a través del receptor
- Android Mediaplayer: problema de setDataSource para el archivo de medios descargado
- Obtener stringXmlContent y escribir a continuación, guardado en el archivo .xml almacenado en sdcard en android ¿cómo se puede?
- No se puede crear una carpeta en sdcard - mkdir siempre devuelve 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 configurar la fuente personalizada para el diálogo de alerta en android?
- Obtener hilo por nombre