I have an issue with writing to sd card on my android 4.4 device. I'm writing an application that gets path to its directory on sd card using the getExternalFilesDirs() method. But when I try to store data in the directory I get an error:
EACCES (Permisson denied)
The applications directories in Android/data/ in both internal memory and on the sd card are owned by different linux users. Any other application on my device works fine. The application works on another device with that sd card.
You need to add this permission in AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
i think you have missplaced this line.
Double check this line
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
where you have put this line?
this line should be outside of <application/> scope
like this
<manifest>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
<application>
...
<activity>
...
</activity>
</application>
</manifest>
For getExternalFilesDirs to return the path of the sdcard, the OEM must have set the SECONDARY_STORAGE environment variable in the device specific init.rc file as mentioned here: https://source.android.com/devices/storage/config-example.html
Look at the source of getExternalFilesDirs here: http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/app/ContextImpl.java#1039
The value is obtained from Environment.buildExternalStorageAppFilesDirs. Look at that source here: http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/os/Environment.java#206
The value is dependent on mExternalDirsForApp, which in turn is populated by reading the contents of SECONDARY_STORAGE variable: http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/os/Environment.java#136
As you can see, if the SECONDARY_STORAGE variable is not set, the sdcard path will not be returned. You can cross-check this by going to adb shell and looking at the output of echo $SECONDARY_STORAGE
use getExternalFilesDir()
It returns the path to files folder inside Android/data/data/your_package/ on your secondary storage SD card. It is used to store any required files for your app (e.g. images downloaded from web or cache files). Once the app is uninstalled, any data stored in this folder is gone too.
This is where you can write file in secondary storage ie(your micro sdcard)
if you want to write outside or the root of the secondary storage you have to use Storage access framework .
Related
I want to create a folder and write a file in real external storage (real extern sd card).
I can write to the internal storage, the external storage, but not to the external sd card (I mean the external storage card you put into a cell phone for more space to store images, videos, ...).
The path of the external sd-card is: "/storage/1234-5678/" and it is on a samsung smartphone.
Reading from the external sd card works without problems.
I am testing with Android 8 (and later with higher versions).
I have searched through internet and try but not getting the result, I have added permissions in Android Manifest file as well.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:ignore="ScopedStorage" />
and an easy test is:
File directory = new File("/storage/1234-5678/new_folder/");
if (!directory.exists()) {
boolean ok = directory.mkdirs();
}
The result to ok is always false, when I use the path to the external / removable sd card.
What I am doing wrong?
Since providing a direct path might be a problem. So I would recommend using the Android file access mechanism.
Mentioned here->https://developer.android.com/training/data-storage/app-specific#external-select-location
Have a look at the second item returned by getExternalFilesDirs().
You can write on that location of the removable micro sd card.
Please read the whole post before down-voting and/or marking it as a duplicate!
I'm working on an app that reads files from within a specific folder on the user's phone - either from the SD card (if there's one) or from the built in storage. Yes, the "READ_EXTERNAL_STORAGE" is mentioned in the manifest and I'm also handling the permission popup for API>23.
I used to simply use
File folder = new File(Environment.getExternalStorageDirectory(), "myfolder");
to get the path of the folder that is stored in the built in storage (32gb for an S7) but now I want to get the path to the SD card. According to pretty much every result google gave me, "Environment.getExternalStorageDirectory()" is supposed to give you the path to the SD card but for me it doesn't (and never has).
I've tested the following with two different Samsung Galaxy S7s, both with Android 7.0, one with an SD card (+ the folder), the other without (+ the folder):
Log.d(tag, System.getenv("EXTERNAL_STORAGE"));
Log.d(tag, System.getenv("SECONDARY_STORAGE"));
Log.d(tag, ""+new File(System.getenv("EXTERNAL_STORAGE")+File.separator+"myfolder").isDirectory());
Log.e(tag, ""+new File(System.getenv("EXTERNAL_STORAGE")+File.separator+ordner).getAbsolutePath());
Log.d(tag, Environment.isExternalStorageRemovable());
Log.d(tag, Environment.getExternalStorageDirectory());
Log.d(tag, Environment.getExternalStorageDirectory().getAbsolutePath());
To my surprise both phones output the same infos:
/sdcard
null
true
/sdcard/myfolder
false
/storage/emulated/0
/storage/emulated/0
According to the file manager app ("My Files"), the built in storage is called "Internal Storage", which makes even less sense (I know the difference between Internal and External Storage in Android).
How do I get the path to the actual SD card (without hardcoding it)?
The only way I found is to semi-hardcode it:
File[] folders = myappcontext.getExternalCacheDirs();
gives you the path to the "cache" folders your app has access to (but that are deleted when you uninstall your app).
If the phone uses a removable SD card (that is currently mounted), the length of the array should be "2":
The path to the "cache" folder in the external (not removable) storage
The path to the "cache" folder on your SD card
They look something like this:
/storage/emulated/0/Android/data/com.mycompany.myapp/cache
/storage/xxxx-xxxx/Android/data/com.mycompany.myapp/cache
... where "x" is the number (id?) of your sd card. I've only been able to test it with 2 different SD cards and both had their own number.
Environment.getExternalStorageDirectory();
should also give you
/storage/emulated/0/
which is the non-hardcoding way of getting access to the external storage. ;)
If you create a new folder on the very first level of your SD card on your PC, its path will be:
/storage/xxxx-xxxx/myfolder
I also have to warn you: While you can read the "myfolder" folder, you can't write in it (will just throw an "Access Denied" exception with Android 7) because of the changes to the whole system that came with Kitkat. But that's a different problem I'm going to address in a new question.
you have to insert the following permission into your application's manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Add this -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>
Is it possible to programmatically copy a file into, or create a symbolic link in the /data/data/application_package/lib directory?
When trying to write to the lib directory, I always get permission denied error.
I have defined
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You cannot write to lib/, however you do not need to.
You can write to any non-reserved location within your your application's private storage area, and you can load a native library from any file on the device for which you have read and execute permission, using System.load() with the full pathname, rather than System.loadLibrary() with the short library name.
The external storage (sdcard) is mounted with a non-executable flag, but a file in your private storage directory would be a workable solution. Just be sure to make it only writable by your application, so that something else can't change it behind your back (it is because you cannot protect external storage files from such modification that the external storage is non-executable)
if you want load so file ,you can use system.load(); you can copy so to data/package name/libs
and use system.load() to load so
in my application i create a temporary file this way
File tmp = File.createTempFile("TEST_", null, getFilesDir());
this resolves in a file that toURI()zed corrisponds to something like
/data/data/it.lorenzoff.test/files/TEST_XXX.tmp
In certain circumstances, i'd like to move this file permanently on sdcard but this code
dest = new File("/sdcard/permanentFile");
tmp.renameTo(dest);
never works.
I'm already using these permissions
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
but renameTo continue returning false.
What i'm doing wrong?
Thanks in advance
L.
The explanation can be found in documentation for File:
Many failures are possible. Some of the more likely failures include:
Write permission is required on the directories containing both the source and destination paths.
Search permission is required for all parents of both paths.
Both paths [must] be on the same mount point. On Android, applications are most likely to hit this restriction when attempting to copy between internal storage and an SD card.
In this case source and target file paths point to different mount points (these two mount points even have different file system). You only option is to manually copy the file to sdcard and then delete the file from internal storage.
How can i check Micro SDCARD is present in device and how i can access that to write some files.
You can connect your device to the computer and mount your micro sd card.
Then you can go ahead and transfer the files like you do for any normal USB drive.
There are several StackOverflow postings on these issues.
You want to use Environment.getExternalStorageDirectory() to get the path to the SD Card. You can then do standard Java File I/O.
Android how to use Environment.getExternalStorageDirectory()
You must use the following permission.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Permission to write to the SD card