Me sale abierto: Error de EACCES (Permiso denegado) cuando intento escribir datos en la tarjeta SD en Android 5.1, ¿por qué?

Necesito guardar algunos datos en la tarjeta SD, tengo que añadir el permiso al archivo AndroidManifest.xml, y puedo obtener el resultado correcto cuando lo pruebo en Android 4.12 móvil.

Pero consigo abierto falló: Error de EACCES (Permiso denegado) cuando lo pruebo en móvil de Android 5.1, ¿por qué?

BTW, he leído el artical Android 6.0 abierto falló: EACCES (Permiso denegado) y Excepción 'abierto falló: EACCES (permiso denegado)' en Android , pero ahora mi móvil es SamSung Android 5.1

Código

private void ActionUploadFiles(Map<String, String> files,IHTTPSession session,String uploadFolder){ try{ Set<String> keys = files.keySet(); for (String key:keys) { String location = files.get(key); File source = new File(location); String filename= session.getParms().get(key); filename=FilenameUtils.getName(filename); File target = new File(uploadFolder,filename); FileUtils.copyFile(source,target); } } catch (Exception e) { Utility.LogError("Upload Error: "+ e.getMessage()); } } 

AndroidManifest.xml

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="info.dodata.wifi"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="com.android.vending.BILLING" /> 

Construir un gradiente

 apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { multiDexEnabled true applicationId "info.dodata.wifi" minSdkVersion 16 targetSdkVersion 23 versionCode 4 versionName "1.04" archivesBaseName = "WiFiFileTransfer-V" + versionName } productFlavors { free { applicationId "info.dodata.wifi" } pro { applicationId "info.dodata.wifi.pro" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' buildConfigField "boolean", "IsDebugMode", "false" } debug { buildConfigField "boolean", "IsDebugMode", "true" } } } 

Le faltan los permisos de tiempo de ejecución introducidos desde Android Lollipop. Lo que puedes hacer es habilitar permiso. Para ello, vaya a

Settings -> Apps -> YOUR_APP -> Permissions

Y habilitar permisos y luego probarlo.

Para agregar permisos en tiempo de ejecución, puede preguntar dentro de onCreate() .

 String[] permission ={Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; if(ContextCompat.checkSelfPermission(EditDisplayPicture.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(EditDisplayPicture.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { ActivityCompat.requestPermissions(YourActivity.this, permission, 1); } } else proceedFurther(); 

Y luego escuchar la aceptación del permiso o la negación de esta manera,

 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { proceedFurther(); } else { Toast.makeText(YourActivity.this, "You need to give permission in order to proceed further.", Toast.LENGTH_SHORT).show(); } } 

Porque tiene targetSdkVersion 23 thats por qué obtiene la excepción de seguridad, tiene que targetSdkVersion 22 a targetSdkVersion 22 o agregar permiso de tiempo de ejecución. Por favor, consulte este enlace https://developer.android.com/training/permissions/requesting.html

Actualización: abierto: EACCES (Permiso denegado)

Comenzando Kitkat, Android restringe el acceso de escritura a SDCARD a aplicaciones de terceros. Presentaron el Storage Access Framework para realizar las operaciones. Para escribir en los archivos de la tarjeta SD, necesitará utilizar estas API.

Para algunos dispositivos que ejecutan Lollipop, puede obtener acceso de escritura a archivos utilizando estos api. Como no he utilizado la api yo mismo, no puedo proporcionarle un fragmento. Pero el enlace seguramente le ayudará a resolver el problema.

Usted puede echar un vistazo a Es Explorer para ver el flujo de cómo manejan este escenario.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.