Best practise for storing files to device - android

Currently
I'm storing my file(images/videos) like this:
File directoryToStore;
directoryToStore = getBaseContext().getExternalFilesDir("MyImages");
This will return this path:
/storage/emulated/0/Android/data/pacageName/files/MyImages/
Now, I want to store the files in root directory /storage/emulated/0/MyImages/. I have tried this by doing:
File directoryToStore;
directoryToStore = new File(Environment.getExternalStorageDirectory(), "MyImages");
This works perfectly fine when running on pre-Marshmallow devices, but In Marshmallow the files are not found.
My Question
How should/can I store files in the root directory so that the file will be found in all API's?

Firstly, make sure you have the permissions bellow in your Android Manifest file, because you are trying to save files into the device's external storage.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Secondly, check if storage permissions are granted to your application (when you execute on Marshmallow or higher OS version devices).
Finally, make sure if there is directory named "MyImages" and check it's chmod. If directory does not exist, create it (mkdir() will create the directory in your example) and then try to save your files again.

Related

Android mkdirs() return false on Android 11 with Environment.getExternalStorageDirectory()

Mkdirs() function is not working on Android 11. every thing is working fine on Android 10 and lower.
Code:
***String path =Environment.getExternalStorageDirectory().getAbsolutePath() + "/My_directory/";
File temp_file = new File(path);
if (!temp_file.exists()){
Boolean can_create= temp_file.mkdir();
}***
the above code returns true in case of Android 10 or lower. but returns false in case of Android 11.
Manifest permissions:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Noting that runtime permission is considered for same (READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE).
Manifest application:
<application
android:requestLegacyExternalStorage="true"
The only way I am able to write in external storage is using getExternalFilesDir() but this is not the root directory.
according to this developer website, we can't create folders any more in the root directory!
Questions so far after checking this:
1- Is it confirmed that in Android 11 we can't create any folder on the root directory? any work around?
2-If yes, what is the way forward to save data in external storage, excluding getExternalFilesDir() ?
3- Why android:requestLegacyExternalStorage="true" is not working?
***String path =Environment.getExternalStorageDirectory().getAbsolutePath() + "/My_directory/";
You cannot create directories in root of external storage on Android 11 devices.
Instead create your own directories in one of the public directories of external storage.
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "My_directory");
Why android:requestLegacyExternalStorage="true" is not working?
android:requestLegacyExternalStorage is no longer works on Android 11+. It is just a helper on Android 10 to give developers more time before migrating to scoped storage. On scoped storage, you need to use URI for creating, renaming, moving files, etc. Thus java.io.File is almost useless now.
Is it confirmed that in Android 11 we can't create any folder on the root directory? any workaround?
No workaround.
BTW, to reduce scoped storage complexity, I've created a library named Simple Storage. It works across API levels.

Android listFiles returns empty array

I uploaded several files to folder "/sdcard/Books/LadySusan" on my android emulator. When I check if file in folder exist, expression
new File("/sdcard/Books/LadySusan/ladysusan_1_austen_64kb.mp3").exists()
returns true, file exists in folder, but when I use
new File("/sdcard/Books/LadySusan").listFiles()
it returns empty array, not null but File[0]. I have permissions to read files from SD card
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and code to request them. Any idea what can be wrong?
Finally I found. It seems to me there is a bug in Android SDK (10.0+). When I started emulator with Android 9.0, it returns files as I expected.
It is not a bug. As of Android 10, external storage access is scoped to app files and media.
This means that your application can only access the files in the app-specific directory (which can be retrieved in code with getExternalFilesDir()) or media in the media store.
As long as you target an Android version lower than API level 30 (Android 11) you can get away with accessing the external storage via the following permission:
<application android:requestLegacyExternalStorage="true" ... >

How to create a folder under /Android/obb?

I'm trying to use expansion files and I found an issue that I'm not able to resolve.
It seems that you can access the /Android/obb folder and eventually delete the /Android/obb/my.package.name directory (tried with some file manager), but I cannot handle this situation whithin the app.
If I just let the Google Downloader library try to download the expansion file it will hang and error (for the missing folder), but it will start if I recreate the folder.
The strange thing is that I'm able to create the folder from other apps (the same file manager that I've used to see the directory) but not from mine!
I tried with
File f = new File(Environment.getExternalStorageDirectory(), "Android/obb/my.package.name");
f.mkdirs();
but it doesn't work.
I've the permissions in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and I'm targeting api 23 and compiling with the 25.
OP dropped the Target SDK to 22 and was able to avoid Dangerous permission work flow which was causing the issue.
I had this same problem, but lowering the Target SDK was not an option.
The Context::getObbDir() method allows access to the expansion folder without the usual security rules. I found that, if the folder doesn't exist, getObbDir() creates it too (You can also double check and create it manually with mkdir()).
Excerpt from the documentation linked above:
Return the primary shared/external storage directory where this application's OBB files (if there are any) can be found. Note if the application does not have any OBB files, this directory may not exist.
This is like getFilesDir() in that these files will be deleted when the application is uninstalled, however there are some important differences:
... Starting in Build.VERSION_CODES.KITKAT, no permissions are required to read or write to the path that this method returns. ...
Starting from Build.VERSION_CODES.N, Manifest.permission.READ_EXTERNAL_STORAGE permission is not required, so don’t ask for this permission at runtime. ...
So you can do something like:
File obbDir = getObbDir();
if (null == obbDir) {
// Storage is not available
} else if (!obbDir.exists() && !obbDir.mkdir()) {
// Failed to create directory. Shouldn't happen but you never know.
}
NOTE: You may need the read/write permissions to access the expansion files within the folder.

How to create folder in Computer\Nexus 5\Internal storage folder

First of all, I'm an android newbie. Now my question...
I want to create a folder with some files, so I can easily access them when I plug in my droid via USB.
"directory.exists" returns true, saying the folder exists, but when I go to Windows File Explorer, Computer\Nexus 5\Internal storage, I do not see my app folder listed in there.
getExternalStorageDirectory returns: /storage/emulated/0/MyAppName
File directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyAppName/");
if (!directory.exists()) {
directory.mkdir();
}
I have added
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in manifest.
What am I doing wrong?
You're not doing anything wrong. Android does.
That MTP connection is unreliable as contents displayed is not in sync with the latest files wrote on the phone.
You can cause a manual rescan or reboot the phone... see below:
android bug
similar question with workarounds

How to rename a file in the root-directory in Android?

I am trying to rename the SystemUI.apk in the directory /system/app to something else on my rooted device (Tablet with ICS) just like Root Browser is able to.
It doesn't work the same way as it works in the /sdcard directory. I tried this:
String s = "/system/app";
File from = new File(s, "SystemUI.apk");
File to = new File(s, "_SystemUI.apk");
from.renameTo(to);
(This code works for file in SD-Card)
And I set the permission to write to the external storage:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
However, there is no such permission for the "internal" storage. Do I need to do this via Runtime.getRuntime().exec(some command)?
Thanks for any help.
You need root access, this can not be done with standard java classes.
Run this commands via SU binary
mv /system/app/SystemUI.apk /system/app/_SystemUI.apk
Obviously you can change the cmd as need to do what you need.

Categories

Resources