open failed: EACCES (Permission denied) - android

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.

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

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

I ran into a similar issue a while back.
Your problem could be in two different areas. It's either how you're creating the file to write to, or your method of writing could be flawed in that it is phone dependent.
If you're writing the file to a specific location on the SD card, try using Environment variables. They should always point to a valid location. Here's an example to write to the downloads folder:
java.io.File xmlFile = new java.io.File(Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
+ "/Filename.xml");
If you're writing the file to the application's internal storage. Try this example:
java.io.File xmlFile = new java.io.File((getActivity()
.getApplicationContext().getFileStreamPath("FileName.xml")
.getPath()));
Personally I rely on external libraries to handle the streaming to file. This one hasn't failed me yet.
org.apache.commons.io.FileUtils.copyInputStreamToFile(is, file);
I've lost data one too many times on a failed write command, so I rely on well-known and tested libraries for my IO heavy lifting.
If the files are large, you may also want to look into running the IO in the background, or use callbacks.
If you're already using environment variables, it could be a permissions issue. Check out Justin Fiedler's answer below.

Add these both permission of read and write, to solve this issue
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Add this below line in Application tag
android:requestLegacyExternalStorage="true"

In my case I had the wrong case in
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
android.permission must be lowercase, and somehow the entire string was uppercase in our source.

I also faced the same issue.
After lot of hard work, I found what was wrong in my case.
My device was connected to computer via USB cable.
There are types for USB connections like Mass Storage, Media Device(MTP), Camera(PTP) etc.
My connection type was - 'Mass Storage', and this was causing the problems.
When I changed the connection type, the issue was solved.
Always remember while accessing filesystem on android device :-
DON'T CONNECT AS MASS STORAGE to the computer/pc.

In my case it was permissions issue.
The catch is that on device with Android 4.0.4 I got access to file without any error or exception. And on device with Android 5.1 it failed with ACCESS exception (open failed: EACCES (Permission denied)).
Handled it with adding follow permission to manifest file:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
So I guess that it's the difference between permissions management in OS versions that causes to failures.

First give or check permissions like
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
If these two permissions are OK, then check your output streams are in correct format.
Example:
FileOutputStream fos=new FileOutputStream(Environment.getExternalStorageDirectory()+"/rahul1.jpg");

I ran into the same problem and found that I have to request the permissions at run time, even if I have declared it in the manifest. Just as stated as Justin Fiedler's answer.
The official documentation about this are here: https://developer.android.com/training/permissions/requesting.html
My implementation is slightly different from Justin Fiedler's answer that it also implement v4 fragment's onRequestPermissionsResult method to handle the permissions request response.
public static final int REQUEST_EXTERNAL_PERMISSION_CODE = 666;
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public static final String[] PERMISSIONS_EXTERNAL_STORAGE = {
READ_EXTERNAL_STORAGE,
WRITE_EXTERNAL_STORAGE
};
public boolean checkExternalStoragePermission(Activity activity) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
return true;
}
int readStoragePermissionState = ContextCompat.checkSelfPermission(activity, READ_EXTERNAL_STORAGE);
int writeStoragePermissionState = ContextCompat.checkSelfPermission(activity, WRITE_EXTERNAL_STORAGE);
boolean externalStoragePermissionGranted = readStoragePermissionState == PackageManager.PERMISSION_GRANTED &&
writeStoragePermissionState == PackageManager.PERMISSION_GRANTED;
if (!externalStoragePermissionGranted) {
requestPermissions(PERMISSIONS_EXTERNAL_STORAGE, REQUEST_EXTERNAL_PERMISSION_CODE);
}
return externalStoragePermissionGranted;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestCode == REQUEST_EXTERNAL_PERMISSION_CODE) {
if (checkExternalStoragePermission(getActivity())) {
// Continue with your action after permission request succeed
}
}
}
}

In my case I used the option android:isolatedProcess="true" for a service in the AndroidManifest.xml.
As soon as I removed it, the error disappeared...

Also I found solving for my way.
Before launch app i granted root to file-explorer and did not disable permission on write/read when exit from app.
My app can not use external memory while i did restrat device for resetting all permissions.

I got the same issue but
Sometimes, the most dificult issue get simple answer.
I recheck the manifest permisions and there WAS_NOT write permision
shame of me!!!

#Uriel Frankel is correct that the Android 10 storage access has changed. But the right way is not to use legacy storage flag but to request the storage of your app like so:
val screenShotDirPath = getApplication<Application>().getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.path
getExternalFilesDir is what you need.

I had the same problem. My app worked on Android 11, but the error showed up in Android 10. Upgrading to Android 11 solved the problem.

If the clients are using Android 6.0, Android added new permission model for (Marshmallow).
Trick: If you are targeting version 22 or below, your application will request all permissions at install time just as it would on any device running an OS below Marshmallow

In my case the issue was the WIFI Configuration that was static had a conflict with another device using the same IP Address.

This error was thrown by another app that I'm sharing my app's file to (using Intent.FLAG_GRANT_READ_URI_PERMISSION)
Turns out, the File Uri has to be provided via FileProvider class as shown here.

I was able to solve this problem by removing
tools:ignore="ScopedStorage" />
this line from
uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" tools:ignore="ScopedStorage"
and also you don't need read permission anymore

Using Android 12 (API 31), I read in OS docs that we must use Manifest main property :
example:
uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
The issue has been solved.

I solved this by using another path:
data/data/[packagename]/cache/...

For those of you who tried all the above solutions and still doesn't solve your error on API 30.
Change targetSdkVersion 30 to 29 in defaultConfig in your build.gradle(app)
Code will look like:-
defaultConfig {
applicationId "com.example.company"
minSdkVersion 16
targetSdkVersion 29
.
.
.
}

in my case i forgot to add / in front of file name after i added i got rid of from it
bitmap.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(Environment.getExternalStorageDirectory()+"/arjunreddy.png"));

Related

Android 10: Delete denied by permission:android.permission.ACCESS_MEDIA_PROVIDER

Target SDK in my project is 31 and when I'm trying to delete a file from DCIM directory, I'm getting following error such as delete denied by permission:android.permission.ACCESS_MEDIA_PROVIDER.
Please consider file path like this: "/storage/emulated/0/DCIM/Screenshots/pic1.jpg"
I have tried so much to find the result every where including stack overflow, but didn't succeeded yet. Even I changed target SDK to lower 30 but not worked.
Following are the solutions that I had already worked on but nothing works:
1.flags in manifest file
android:requestLegacyExternalStorage="true"
android:preserveLegacyExternalStorage="true"
2.permissions in manifest file
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="40"
tools:replace="android:maxSdkVersion" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
Please find the attached code
val fileToDelete = File("/storage/emulated/0/DCIM/Screenshots/pic1.jpg")
fileToDelete.delete()
NOTE: filepath is hardcoded only to explain better
Please find the attached log
2022-03-21 11:22:35.331 8639-20226/com.filepickerdemo D/ContentResolver: delete denied by permission:android.permission.ACCESS_MEDIA_PROVIDER#content://media/external/images/media#_data = ?#/storage/emulated/0/DCIM/Screenshots/pic1.jpg
What else should I put in my code to solve this issue. Thanks in advance.
To delete media files in android 10 and above, You can try contentresolver API.
You need to pass the media's content uri to the 'contentResolver.delete()' method & you will be able to do it easily.
Here is my post on how to do that using Java - Scoped Storage in Android — Writing & Deleting Media Files

I want to communicate with kernel to set up SADB in Android NDK but getting Permission Denied Error

I am using following code and getting permission denied error.
if ((mSockFd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
LOGE("IPSec Init : PF_KEY socket creation failed");
LOGE("mSockFd : %d, Error no : %d",mSockFd,errno);
LOGE("Error String : %s",strerror(errno));
}
I have added following permission in AndroidMenifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Please help me solve this problem.
Where
PF_KEY is a new socket protocol family used by trusted privileged
key management applications to communicate with an operating
system's key management internals
To open SOCK_RAW type socket you need to have root privileges. If you are trying to run this on Mobile then phone must be rooted. Or try to implement in Linux Machine you will get root privilege easily.

saving file on sdcard with permission error

After countless searching I've managed to find path to my sdcard not the android emulated storage. But when I try to make .txt folder there it ends up with error
/storage/37F0-1515/DCIM/100MEDIA/test.txt: open failed: EACCES (Permission denied)
I don't know why because I have permissions for
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and also I've enabled the permissions with
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, request2);
}
Here is the code that I'm using
File sdCard = new File("/storage/37F0-1515/DCIM/100MEDIA");
File dir = new File(sdCard.getAbsolutePath());
if (!dir.exists()) {
dir.mkdirs();
}
final File file = new File(dir, "test" + ".txt");
try {
BufferedWriter bufferedWriter = null;
bufferedWriter = new BufferedWriter(new FileWriter(file));
bufferedWriter.write("test");
bufferedWriter.close();
}
catch(Exception e){Log.v("myApp", e.toString());}
I don't know why android won't let me write to sdcard. Do I need some other permissions ?
I don't know why because I have permissions for
Those permissions are for external storage, not removable storage.
I don't know why android won't let me write to sdcard
You do not have arbitrary filesystem access to removable storage on Android 4.4+.
Try using these methods-
Check if the uses-permission statements are in the right place, they should be below <manifest> and above <application> tags. The correct format -
<manifest>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
<application>
...
<activity>
...
</activity>
</application>
</manifest>
Starting from Android Kitkat, there is a new storage policy -
The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions. Restricting writes in this way ensures the system can clean up files when applications are uninstalled.
This can however be exploited without rooting(although I have not tried this one), as mentioned here
EDIT -
The above mentioned exploit won't work for Android 5+. There is no standard solution to this problem. Some exploits may be available but they will be device-specific/not reliable/root-access dependent.
However, tools like the Storage Access Framework can be used.

How to have the necessary permission to Write File in Removal External Storage in Android without resorting to Root

I'm using Samsung J7 Unrooted for Testing,
My AndroidManifest.xml contains the necessary permissions to write to external storage
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
I don't encounter any error when I used the code:
File myFile = new File("sdcard/Billing/mysdfile.txt");
It save the file on the Device Storage.
But when I specify the removable SDCard using the code:
File myFile = new File("/storage/extSdCard/mysdfile.txt");
I encounter the error :
open failed: EACCES (Permission denied)
I've tried different ways to point to the removable SDCard but encountered the same "open failed: EACCES (Permission denied)" error.
I've checked if I have the necessary permissions to write to external storages and it always say "Granted"
public void verifyStoragePermissions() {
if (ContextCompat.checkSelfPermission(InitActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getBaseContext(), "Denied", Toast.LENGTH_SHORT).show();
if (ActivityCompat.shouldShowRequestPermissionRationale(InitActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
}
}else{
Toast.makeText(getBaseContext(), "Granted",Toast.LENGTH_SHORT).show();
}
}
I've tried almost everything suggested listed in the google search but to no avail. There are a Few who advises to "Root" the phone but that is unfortunately not an option for me...
Hope someone can help me gain the needed permission rights to save files in my removable external storage without resorting to "Rooting" the phone.

Permission denied at createNewFile() in /sdcard

i have a piece of code, which creates a file on the /sdcard on the ExternalStorage ("internal" 8GB Memory of a GalaxyTab2 7.0).
directory = new File(Environment.getExternalStorageDirectory(),
"/logs");
directory.mkdirs();
log = new File(directory.getPath() + "/" + this.filename);
boolean created = log.createNewFile();
At the last line i get following error:
... java.io.IOException: open failed: EACCES (Permission denied)
... at java.io.File.createNewFile(File.java:948)
I have
set the permission for writing external storage in the right place in manifest
checked, that the memory is not mounted at pc
checked, that the /logs/ folder hat the correct permissions at file explorer
read every single stackoverflow thread about the topic - nothing worked
Has anyone a hint, which can cause this behavior?
best regards
add below permission in manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I used a (self-written) library, which manages all the memory access. This library project has the WRITE_EXTERNAL_STORAGE permission. The App, which references this library must also have this permission, even if it is not directly accessing the storage.

Categories

Resources