0

I am trying to save data in external storage. but I get a FileNotFoundException.

I looked up online and included the required permissions in Manifest and created the folder by 'mkdirs()' I am testing it on the emulator - Nexus 6 API 23.

Could you suggest where am I doing it wrong.

 @Override
    public void saveExternalPublic(String data) {
        File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
        File myFile = new File(folder, "myData4.txt");
        folder.mkdirs();
        writeData(myFile, data);
    }

 @Override
    public void writeData(File myFile, String data) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(myFile);
            fileOutputStream.write(data.getBytes());
            cacheSaveView.showMessage(data + " was written successfully "+ myFile.getAbsolutePath());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if(null != fileOutputStream) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

Permission

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Error log

11-30 00:51:43.178 23490-23490/com.example.rao.cachingsample W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Download/myData4.txt: open failed: EACCES (Permission denied)
11-30 00:51:43.180 23490-23490/com.example.rao.cachingsample W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:452)
11-30 00:51:43.180 23490-23490/com.example.rao.cachingsample W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
11-30 00:51:43.180 23490-23490/com.example.rao.cachingsample W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
11-30 00:51:43.181 23490-23490/com.example.rao.cachingsample W/System.err:     at com.example.rao.cachingsample.Caching.Presenter.CacheSavePresenterImpl.writeData(CacheSavePresenterImpl.java:60)
11-30 00:51:43.181 23490-23490/com.example.rao.cachingsample W/System.err:     at com.example.rao.cachingsample.Caching.Presenter.CacheSavePresenterImpl.saveExternalPublic(CacheSavePresenterImpl.java:53)
11-30 00:51:43.181 23490-23490/com.example.rao.cachingsample W/System.err:     at com.example.rao.cachingsample.Caching.View.FCacheSave.saveExternalPublic(FCacheSave.java:82)
11-30 00:51:43.181 23490-23490/com.example.rao.cachingsample W/System.err:     at com.example.rao.cachingsample.Caching.View.FCacheSave_ViewBinding$4.doClick(FCacheSave_ViewBinding.java:63)
11-30 00:51:43.182 23490-23490/com.example.rao.cachingsample W/System.err:     at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
11-30 00:51:43.182 23490-23490/com.example.rao.cachingsample W/System.err:     at android.view.View.performClick(View.java:5198)
11-30 00:51:43.183 23490-23490/com.example.rao.cachingsample W/System.err:     at android.view.View$PerformClick.run(View.java:21147)
11-30 00:51:43.184 23490-23490/com.example.rao.cachingsample W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
11-30 00:51:43.185 23490-23490/com.example.rao.cachingsample W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
11-30 00:51:43.185 23490-23490/com.example.rao.cachingsample W/System.err:     at android.os.Looper.loop(Looper.java:148)
11-30 00:51:43.185 23490-23490/com.example.rao.cachingsample W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
11-30 00:51:43.192 23490-23490/com.example.rao.cachingsample W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
11-30 00:51:43.193 23490-23490/com.example.rao.cachingsample W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-30 00:51:43.198 23490-23490/com.example.rao.cachingsample W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
11-30 00:51:43.199 23490-23490/com.example.rao.cachingsample W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
11-30 00:51:43.211 23490-23490/com.example.rao.cachingsample W/System.err:     at libcore.io.Posix.open(Native Method)
11-30 00:51:43.215 23490-23490/com.example.rao.cachingsample W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
11-30 00:51:43.216 23490-23490/com.example.rao.cachingsample W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:438)
BRDroid
  • 3,920
  • 8
  • 65
  • 143
  • 1
    you need to ask **[runtime Permission](https://developer.android.com/training/permissions/requesting.html)** – Goku Nov 30 '17 at 08:05
  • where have you declared your permissions in manifest ? – Umair Nov 30 '17 at 08:06
  • 1
    Possible duplicate of [How to check Grants Permissions at Run-Time?](https://stackoverflow.com/questions/30549561/how-to-check-grants-permissions-at-run-time) – Goku Nov 30 '17 at 08:06
  • Did you ask runtime permission? – Bek Nov 30 '17 at 08:07
  • I did not ask permissions at run time. okay I will do that. – BRDroid Nov 30 '17 at 08:09
  • `and created the folder by 'mkdirs()' `. No. The folder was not created. You asked mkdirs() to create a folder. And you should have looked at the return value. As it did return false indicating that it did not succeed. – greenapps Nov 30 '17 at 09:26

4 Answers4

0

You should create the directory first and the file after.

    File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    folder.mkdirs();
    File myFile = new File(folder, "myData4.txt");
    writeData(myFile, data);
  • The sequence did not matter. And your code is bad like original while not checking the return value of mkdirs. – greenapps Nov 30 '17 at 09:27
0

Go to this link for Runtime permission. https://www.androidhive.info/2016/11/android-working-marshmallow-m-runtime-permissions/

From API 23 means Android 6.0(lollipop) only Manifest Permission is not enough to access any permission. You have to provide runtime permission dialog to ask users for permission at the related screen.

Sneha Sarkar
  • 731
  • 6
  • 19
0

From Android 6, you have to request permissions at runtime. See more here.

For testing, you are able to enable them by yourself. You choose Setting->Apps->choose your app->select the Permission section-> enable all permissions

To know which permissions need to request at runtime. You should have a look my answer.

John Le
  • 1,116
  • 9
  • 12
0

you need to ask permissions at run time in android API 23+ even if you have already declared them in manifest

public static void StoragePermissions(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
    );
   }
 }

And also check if you have declared manifest permissions in application Tag or not. Check more of the info at the following links: Exception 'open failed: EACCES (Permission denied)' on Android and more at Android Docs

Umair
  • 6,366
  • 15
  • 42
  • 50