Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

open failed: EACCES (Permission denied)

I am having a very weird problem with storage accessing on some devices. The app works on my testing devices (Nexus 4 & 7, Samsung GS5). All my devices running Android 4.4.2. But I received many emails from users saying that the app can not write to the storage (neither the internal storage nor the sd card). From the log file received from user feedback, I can see the problem is the following code:

try {     if (fStream == null) {     fStream = new FileOutputStream(filename, true); }     fStream.write(data, 0, bytes);     return; } catch (IOException ex) {     ex.printStackTrace(); } 

It throws exception at the line fStream = new FileOutputStream(filename, true); when creating FileOutputStream.

The stack log is:

W/System.err( 8147): Caused by: java.io.FileNotFoundException: /storage/emulated/0/my_folder/test_file_name.png: open failed: EACCES (Permission denied) w/System.err( 8147):    at libcore.io.IoBridge.open(IoBridge.java:409) W/System.err( 8147):    at java.io.FileOutputStream.<init>(FileOutputStream.java:88) W/System.err( 8147):    at java.io.FileOutputStream.<init>(FileOutputStream.java:128) W/System.err( 8147):    at myapp.save(SourceFile:515) W/System.err( 8147):    ... 8 more W/System.err( 8147): Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied) W/System.err( 8147):    at libcore.io.Posix.open(Native Method) W/System.err( 8147):    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) W/System.err( 8147):    at libcore.io.IoBridge.open(IoBridge.java:393) W/System.err( 8147):    ... 11 more 

In the AndroidManifest.xml I have the following permissions declared:

 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19"/>     <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 android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

I've confirmed that the users are using the correct app's private on the SD card. And what's more weird is that it fails to write to internal storage as well. How can this happen if I have both read & write permissions? The users say they are not connecting their devices to the PC at that time.

Update

It turns out I am calling open and close FileOutputStream too frequently, which throws the FileNotFoundException at some point. Sounds more like a threading issue.

like image 855
user3613696 Avatar asked May 07 '14 20:05

user3613696


2 Answers

Apps targeting Android Q - API 29 by default are given a filtered view into external storage. A quick fix for that is to add this code in the AndroidManifest.xml:

<manifest ... >     <!-- This attribute is "false" by default on apps targeting Android Q. -->     <application android:requestLegacyExternalStorage="true" ... >      ...     </application> </manifest> 

Read more about it here: https://developer.android.com/training/data-storage/compatibility

like image 192
Uriel Frankel Avatar answered Sep 22 '22 02:09

Uriel Frankel


For API 23+ you need to request the read/write permissions even if they are already in your manifest.

// 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" /> 
like image 40
Justin Fiedler Avatar answered Sep 23 '22 02:09

Justin Fiedler