Permission Denied trying to write in cache directory - android

Trying to download file in cache directory like context.getExternalCacheDir() or context.getCacheDir() on some devices i'm getting a Permission Denied error;
Referring to this guys (https://www.youtube.com/watch?v=5xVh-7ywKpE&t=1580s) i don't need to request permission to access cache directory of my application
Error message I've got from Huawei 4x:
java.io.FileNotFoundException: /storage/3C11-1816/Android/data/{my app package}/cache/194751d974025fd4109902d9600b6a09.mp3: open failed: EACCES (Permission denied)
How can i solve that problem?
Here is my directory provider where i download files
public File provide() {
File external = mContext.getExternalCacheDir();
File cacheDir = external != null ? external : mContext.getCacheDir();
if (!cacheDir.exists()) {
cacheDir.mkdirs();
}
return cacheDir;
}

Related

java.io.FileNotFoundException open failed: ENOENT (No such file or directory)

I have a temp file that is made for creating an image from a cropping library and I can see the file in Device File Explorer but when I try to open the file I get this error:
java.io.FileNotFoundException: file:/data/user/0/com.example.demo/cache/.tmp/cropped1651879842159823361.png: open failed: ENOENT (No such file or directory)
This is how that file is created:
val croppedImageFile = File.createTempFile("cropped", ".png", viewModel.tempPath)
val destinationUri = Uri.fromFile(croppedImageFile)
viewModel.tempPath is just the following:
viewModel.tempPath = "${this.cacheDir}/.tmp"
I can see that file got created and is valid, but when I try to access it, it claims it doesn't exists. I simply open the file by doing File(uri.toString()). in the view model
I'm not sure what is wrong and why it can't find the file. If this matters, I'm using an emulator that has google play and it's Android 11.
You need to open the file using new File(uri.getPath()).
uri.toString() returns the URI as a string, that means "file://path/to/file" which is not a valid path.

Request write permission for SD Card

I am trying to write data to the SD card for android using the permission_handler package but it seems that PermissionGroup.storage only request permission for internal storage. Is what I'm trying to do possible?
This is the my code for requesting permission:
Future<bool> _checkPermission() async {
PermissionStatus permission = await Permission.storage.status;
print(permission);
if (permission != PermissionStatus.granted) {
if (await Permission.storage.request().isGranted) {
return true;
}
} else {
return true;
}
return false;
}
And this is the error I get when I try to create a folder on the sd card.
PS: This works for internal storage
Unhandled Exception: FileSystemException: Creation failed, path = '/storage/1EFF-130C/Music/2020' (OS Error: Permission denied, errno = 13)
Micro SD cards are read only on modern Android devices.
Only one app specific directory is writable.
On Android Q+ the card is not even readable except for that directory.
You can however use SAF for full access.

EACCES (Permission denied) with granted permissions in API 17 (4.2)

I have an application that correctly works with files in "external storage".
Recently I upgrade Android Studio from 2.2 to 2.3. And after this upgrade an application fails when creating files in external storage with EACCESS (Permission denied).
Affected versions
I have error in Android 4.0.3, 4.1, 4.2
I do not have error in Android 4.3, 4.4 and higher.
Code example
It is part of code, that fails
File tempFile = new File(Environment.getExternalStorageDirectory().toString() + "/.tmpfile");
if (!tempFile.exists() && !tempFile.createNewFile()) {
throw new IOException("Cannot create temp file");
}
And in method createNewFile() throws exception with EACCES:
java.io.IOException: open failed: EACCES (Permission denied)
at java.io.File.createNewFile(File.java:948)
...
Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
at java.io.File.createNewFile(File.java:941)
...
java.io.IOException: open failed: EACCES (Permission denied)
at java.io.File.createNewFile(File.java:948)
...
Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
at java.io.File.createNewFile(File.java:941)
... 15 more
Of course, I have <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in AndroidManifest.xml.
Application have granted permissions. I check it in main activity via:
if (checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_CODE);
}
and have requestCode == PackageManager.PERMISSION_GRANTED is true.
The most strange: when I try to rollback my code to previous stable production releases (when files was succesfully created in 2.2) and create build, I get the same error! :( I get this error in emulator, in real devices.
Why? What was changed in Android Studio 2.3, that I cant create any file in old Android?
UPD
Thanks for Nick, he helps me to find difference in behaviour. I test below lines on Android 4.2 and 4.3, and get:
Environment.getExternalStorageDirectory()
4.2: '/mnt/sdcard'
4.3: '/storage/sdcard'
ContextCompat.getExternalFilesDirs(this, null)
4.2: {null} (array with one null-element)
4.3: '/storage/sdcard/Android/data/com.example/files'
Environment.getExternalStorageState()
4.2: 'removed'
4.3: 'mounted'
Your problem concerns changes made in Android 4.4. To quote documentation:
Sometimes, a device [...] may also offer an SD card slot. When such a device is running Android 4.3 and lower, the getExternalFilesDir() method provides access to only the internal partition and your app cannot read or write to the SD card
The documentation also offers a solution:
If you'd like to access both possible locations while also supporting Android 4.3 and lower, use the support library's static method
This refers to using ContextCompat rather than the core Android method
File[] dirs = ContextCompat.getExternalFilesDirs(ctx, null); //null, no specific sub directory
if (dirs.length > 0) {
File ext = dirs[dirs.length -1]; //Just presuming SD card will be the last one offered
//use ext here like you used tempFile before
}
You should also make sure that the media is available, as lower Android versions are more likely to be using low performance devices. Do that with the Environment class
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
//safe
}
EDIT
So a complete solution might be to replace
File tempFile = new File(Environment.getExternalStorageDirectory().toString() + "/.tmpfile");
With
File tempFile = null;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
//compatible for ALL the versions
File[] dirs = ContextCompat.getExternalFilesDirs(ctx, null); //null, no specific sub directory
if (dirs.length > 0) {
tempFile = dirs[dirs.length -1];
}
}
if (tempFile != null) {
//here continue exactly as you did before
if (!tempFile.exists() && !tempFile.createNewFile()) {
throw new IOException("Cannot create temp file");
}
} else {
//handle case where sd card isnt reachable (notification etc)
}

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.

Android - Error: open failed: EACCES (Permission denied)

I'm using BeagleBuddy mp3 tag editor to make changes to mp3 files on the internal / external storage... Works fine on some phones... but on certain phones, I get this error... (Samsung S4, Note 3) etc...
open failed: EACCES (Permission denied)
I have in my manifest...
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Still no luck... Any suggestions?
I've read a lot about how Android is protecting the external card from edits on some phones... is there a way to get around this?
I've used several different methods to get the external drive... Some work on some phone, some don't work...
This is what I am currently using:
public static File getRemovableStorage()
{
String value = System.getenv("SECONDARY_STORAGE");
if (!TextUtils.isEmpty(value))
{
String[] paths = value.split(":");
for (String path : paths)
{
File file = new File(path);
if (file.isDirectory())
{
return file;
}
}
}
return null; // Most likely, a removable micro sdcard doesn't exist
}
It finds all of the files on the external drive great... I just get that error when I try to update an mp3 tag on the external drive.

Categories

Resources