EACCESS Permiso denegado en Android
Al escribir el archivo en la tarjeta externa de SD estoy recibiendo un error EACCESS permiso denegado. He fijado el permiso <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Pero cuando leo el archivo con éxito puedo leerlo pero no puedo escribir el archivo. El código que estoy usando para escribir el archivo en la tarjeta SD es:
String path="mnt/extsd/Test"; try{ File myFile = new File(path, "Hello.txt"); //device.txt myFile.createNewFile(); FileOutputStream fOut = new FileOutputStream(myFile); OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut); myOutWriter.append(txtData.getText()); myOutWriter.close(); fOut.close(); Toast.makeText(getBaseContext(),"Done writing SD "+myFile.getPath(),Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(getBaseContext(), e.getMessage(),Toast.LENGTH_SHORT).show(); System.out.println("Hello"+e.getMessage()); } }
La ruta para la tarjeta de almacenamiento externo es mnt/extsd/
. Es por eso que no soy capaz de usar Environment.getExternalStorageDirectory().getAbsolutePath()
que me está dando una ruta mnt/sdcard
y esta ruta es para la ruta de almacenamiento interno en mi tableta. Por favor, sugiera por qué esto es tan n ¿Cómo puedo resolver esto
- Almacenamiento de datos en la tarjeta SD en Android
- ¿Hay una manera de saber si el sdcard está montado vs no instalado en absoluto?
- Compruebe si la tarjeta SD está disponible o no se puede programar
- Donde está mi aplicación / Los datos aparecen vacíos
- No obtener las intenciones relacionadas con la tarjeta SD a mi receptor de difusión
- Android cómo usar Environment.getExternalStorageDirectory ()
- Cómo comprobar si la carpeta recién creada está presente en la tarjeta SD en Android
- Preferexternal en manifesto no funciona cuando se instala desde el mercado
- Cómo diferenciar entre la ruta de la tarjeta SD interna y externa en android
- Dispositivos Android con Environment.getExternalStorageDirectory ()! = / Mnt / sdcard /?
- No se pueden agregar datos a Android sdcard en el emulador
- GetExternalStorageDirectory no funciona
- Buscar todos los archivos en la tarjeta SD
Recuerdo que Android tiene una compatibilidad parcial con múltiples almacenamiento desde Honeycomb, y el almacenamiento primario (el que obtiene de Environment.getExternalStorageDirectory, normalmente parte de la tarjeta interna eMMC) aún está protegido por el permiso WRITE_EXTERNAL_STORAGE
, pero los almacenes secundarios (como la verdadera tarjeta SD extraíble) están protegidos por un nuevo permiso android.permission.WRITE_MEDIA_STORAGE
, y el nivel de protección es signatureOrSystem, véase también la discusión en este artículo .
Si este es el caso, entonces parece imposible para una aplicación normal escribir nada en el sdcard real sin una firma de plataforma …
Desde API de nivel 19, Google ha añadido API .
-
Context.getExternalFilesDirs()
-
Context.getExternalCacheDirs()
-
Context.getObbDirs()
No se debe permitir que las aplicaciones escriban en dispositivos de almacenamiento externos secundarios, excepto en sus directorios específicos de paquetes según lo permitan los permisos sintetizados. Al restringir las escrituras de esta forma, el sistema puede limpiar los archivos cuando se desinstalan las aplicaciones.
A continuación se muestra cómo obtener un directorio específico de la aplicación en tarjetas SD externas con rutas absolutas.
Context _context = this.getApplicationContext(); File fileList2[] = _context.getExternalFilesDirs(Environment.DIRECTORY_DOWNLOADS); if(fileList2.length == 1) { Log.d(TAG, "external device is not mounted."); return; } else { Log.d(TAG, "external device is mounted."); File extFile = fileList2[1]; String absPath = extFile.getAbsolutePath(); Log.d(TAG, "external device download : "+absPath); appPath = absPath.split("Download")[0]; Log.d(TAG, "external device app path: "+appPath); File file = new File(appPath, "DemoFile.png"); try { // Very simple code to copy a picture from the application's // resource into the external file. Note that this code does // no error checking, and assumes the picture is small (does not // try to copy it in chunks). Note that if external storage is // not currently mounted this will silently fail. InputStream is = getResources().openRawResource(R.drawable.ic_launcher); Log.d(TAG, "file bytes : "+is.available()); OutputStream os = new FileOutputStream(file); byte[] data = new byte[is.available()]; is.read(data); os.write(data); is.close(); os.close(); } catch (IOException e) { // Unable to create file, likely because external storage is // not currently mounted. Log.d("ExternalStorage", "Error writing " + file, e); } }
La salida de registro de arriba se ve así:
context.getExternalFilesDirs() : /storage/extSdCard/Android/data/com.example.remote.services/files/Download external device is mounted. external device download : /storage/extSdCard/Android/data/com.example.remote.services/files/Download external device app path: /storage/extSdCard/Android/data/com.example.remote.services/files/
Solucioné este problema al eliminar el android:maxSdkVersion="18"
en uses-permission
en el archivo de manifiesto. Es decir, use esto:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
en lugar de:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
Compruebe si el usuario tiene permiso de almacenamiento externo o no. Si no, utilice el directorio caché para guardar el archivo.
final boolean extStoragePermission = ContextCompat.checkSelfPermission( context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; if (extStoragePermission && Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) { parentFile = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); } else{ parentFile = new File(context.getCacheDir(), Environment.DIRECTORY_PICTURES); }