10

I need to save some data to SD card , I have add the permission to AndroidManifest.xml file, and I can get the correct result when I test it in Android 4.12 mobile.

But I get open failed: EACCES (Permission denied) error when I test it in Android 5.1 mobile, why?

BTW, I have read the artical Android 6.0 open failed: EACCES (Permission denied) and Exception 'open failed: EACCES (Permission denied)' on Android , but now my mobile is SamSung Android 5.1

Code

 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" />

build.gradle

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"
        }
    }

}
Community
  • 1
  • 1
HelloCW
  • 843
  • 22
  • 125
  • 310

4 Answers4

3

You are missing the run-time permissions introduced from Android Lollipop. What you can do is enable permission. To do this, go to

Settings -> Apps -> YOUR_APP -> Permissions

and enable permissions and then test it.

For adding run-time permission, you can ask inside 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();

And then listen for permission acceptance or denial like this,

@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();
    }
}
Waqas Ahmed Ansari
  • 1,683
  • 15
  • 30
  • Thanks! but I think it should be 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) ... right? – HelloCW Apr 09 '17 at 13:12
  • If you want to proceed when both permissions are enabled, then you should `AND` the permissions. In anyways, `&&` is recommended because you always ask permission you need in your app and it's pointless to proceed if anyone is enabled. – Waqas Ahmed Ansari Apr 10 '17 at 04:10
  • Thanks! Would you please have a look at http://stackoverflow.com/questions/33030933/android-6-0-open-failed-eacces-permission-denied – HelloCW Apr 10 '17 at 12:56
  • Ronny Kibet use OR instead of AND – HelloCW Apr 10 '17 at 12:58
  • It's basic programming concept, you can use it how you want it to be. You know what does `&&` and `||` mean, so use it according to your need. – Waqas Ahmed Ansari Apr 10 '17 at 13:03
0

because you have targetSdkVersion 23 thats why you get Security exception, you have to downgrade to targetSdkVersion 22 or add run time permission. please check this link https://developer.android.com/training/permissions/requesting.html

Update : open failed: EACCES (Permission denied)

Community
  • 1
  • 1
Rajesh
  • 2,618
  • 19
  • 25
  • Thanks! I have set targetSdkVersion 22, but I still get open failed: EACCES (Permission denied) ! – HelloCW Mar 08 '17 at 09:59
  • You will failed to notice one thing **If the device is running Android 5.1 or lower, or your app's target SDK is 22 or lower** and **If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher** This answer wont help – Ashwin Mothilal Mar 14 '17 at 10:13
0

Starting Kitkat, Android restricted write access to SDCARD to third party applications. They introduced the Storage Access Framework for performing the operations. To write to files on the SDCard you will need to use these API's.

For Some devices running Lollipop, you can gain write access to files using these api's. As I haven't used the api myself, I cannot provide you with a snippet. But the link will surely help you solve the problem.

You can take a look at Es Explorer to see the flow of how they handle this scenario.

Alim Parkar
  • 632
  • 3
  • 9
0

Maybe this is because your device is not allowing the application to access the storage.

Generally this error comes with the permission denied, so just go to the settings in your device if you are using the physical device as emulator to run the app and then go to application manager. Find your app and go to permissions and then allow the permission storage for your app and try again.

3N1GM4
  • 3,372
  • 3
  • 19
  • 40