android - card - Cómo evitar el "permiso EACCES denegado" EN LA TARJETA SDC con la versión KITKAT 4.4.2. Nueva política de google
android 4.4 sd card restrictions sin root (4)
Con la versión de Android kitkat 4.4.2 es una nueva política de Google implementada para el acceso de escritura, que no entiendo hasta ahora.
Leí mucho sobre este problema con otras aplicaciones. Reciben un "permiso EACCES denegado". Mi aplicación necesita escribir / descomprimir un archivo zip, también escribir en una base de datos sqlite.
¿Cómo puede resolverse este problema de permiso EACCES con la versión de Android 4.4.2 KITKAT?
De la documentación:
A partir de Android 4.4, los dispositivos de almacenamiento externo múltiples surgen a través de Context.getExternalFilesDirs (), Context.getExternalCacheDirs () y Context.getObbDirs () .
Los dispositivos de almacenamiento externo que surgen a través de estas API deben ser una parte semipermanente del dispositivo (como una ranura para tarjetas SD en el compartimiento de la batería). Los desarrolladores esperan que los datos almacenados en estas ubicaciones estén disponibles durante largos períodos de tiempo. Por esta razón, los dispositivos de almacenamiento transitorio (como las unidades de almacenamiento masivo USB) no deben aparecer a través de estas API.
El permiso WRITE_EXTERNAL_STORAGE solo debe otorgar acceso de escritura al almacenamiento externo primario en un dispositivo. 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 manera, se garantiza que el sistema puede limpiar los archivos cuando se desinstalan las aplicaciones.
Encontré una solución de trabajo para este problema en el foro xda ; no hay necesidad de enraizamiento.
Aquí hay un ejemplo:
/**
* Returns an OutputStream to write to the file. The file will be truncated immediately.
*/
public OutputStream write()
throws IOException {
if (file.exists() && file.isDirectory()) {
throw new IOException("File exists and is a directory.");
}
// Delete any existing entry from the media database.
// This may also delete the file (for media types), but that is irrelevant as it will be truncated momentarily in any case.
String where = MediaStore.MediaColumns.DATA + "=?";
String[] selectionArgs = new String[] { file.getAbsolutePath() };
contentResolver.delete(filesUri, where, selectionArgs);
ContentValues values = new ContentValues();
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
Uri uri = contentResolver.insert(filesUri, values);
if (uri == null) {
// Should not occur.
throw new IOException("Internal error.");
}
return contentResolver.openOutputStream(uri);
}
La única solución a partir de ahora es que este problema solo puede solucionarse arraigando su teléfono y cambiando los permisos de la tarjeta SD desde el directorio raíz utilizando exploradores de archivos, lo cual no se recomienda ya que anula la garantía de su teléfono y también activa algunas aplicaciones de seguridad como KNOX en teléfonos como Samsung Galaxy S5 S4 Note3 y también Note2.
Lo siento por publicar este hecho amargo.
Esperemos una actualización del propio google que nos pueda sacar de esta situación.
Pero también piensa antes de actualizar Jellybean a Kitkat, ya que JB es el sistema operativo más conveniente de Android. y la diferencia b / w JB & Kitkat no es tan alta.
Espero haberte ayudado ...
Necesitas preguntarle al androide sobre el permiso en tiempo real como este:
private static final int MY_PERMISSIONS_REQUEST_STORAGE = 123456;
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_STORAGE);
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent chooserIntent = cameraHelper.openImageIntent();
startActivityForResult(chooserIntent, MY_PERMISSIONS_REQUEST_STORAGE);
}
}
}
}