Excepción 'error de apertura: EACCES (permiso denegado)' en Android
estoy obteniendo
error de apertura:
EACCES (Permission denied)
en la líneaOutputStream myOutput = new FileOutputStream(outFileName);
Revisé la raíz y lo intenté android.permission.WRITE_EXTERNAL_STORAGE
.
¿Como puedo solucionar este problema?
try {
InputStream myInput;
myInput = getAssets().open("XXX.db");
// Path to the just created empty db
String outFileName = "/data/data/XX/databases/"
+ "XXX.db";
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
buffer = null;
outFileName = null;
}
catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Google tiene una nueva función en Android Q : vista filtrada para almacenamiento externo. Una solución rápida para esto es agregar este código en el archivo AndroidManifest.xml:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
Puede leer más al respecto aquí: https://developer.android.com/training/data-storage/use-cases
Editar: Estoy empezando a recibir votos negativos porque esta respuesta no está actualizada para Android 11. Entonces, quien vea esta respuesta, vaya al enlace de arriba y lea las instrucciones.
Para API 23+, debe solicitar los permisos de lectura/escritura incluso si ya están en su manifiesto.
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Para obtener documentación oficial sobre cómo solicitar permisos para API 23+, consulte https://developer.android.com/training/permissions/requesting.html
Tuve el mismo problema... <uses-permission
Estaba en el lugar equivocado. Esto es correcto:
<manifest>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
<application>
...
<activity>
...
</activity>
</application>
</manifest>
La uses-permission
etiqueta debe estar fuera de la application
etiqueta.
Agregue android:requestLegacyExternalStorage="true" al manifiesto de Android. Funciona con Android 10 (Q) en SDK 29+
o después de migrar Android X.
<application
android:name=".MyApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon=""
android:label=""
android:largeHeap="true"
android:supportsRtl=""
android:theme=""
android:requestLegacyExternalStorage="true">
He observado esto una vez al ejecutar la aplicación dentro del emulador. En la configuración del emulador, debe especificar correctamente el tamaño del almacenamiento externo ("Tarjeta SD"). De forma predeterminada, el campo "almacenamiento externo" está vacío, y eso probablemente significa que no existe dicho dispositivo y se lanza EACCES incluso si se otorgan permisos en el manifiesto.