My android phone is Sony Z3, and the version is Android 6.0.1, when I use
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) to get the SDCard DCIM path, which returns path is /storage/emulated/0/DCIM,
but my sdcard real path is /storage/3FC5-160A/DCIM. Any one know how to get the correct sdcard path on Android 6? Thanks.
Also, I have add the external storage read and write permission in manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I had to do this specifically for M. Get all the dirs with context.getExternalCacheDirs() then check if it's removable
// For Marshmallow, use getExternalCacheDirs() instead of System.getenv("SECONDARY_STORAGE")
// to determine if there are mounted SD cards
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
File[] externalCacheDirs = context.getExternalCacheDirs();
for (File file : externalCacheDirs) {
if (Environment.isExternalStorageRemovable(file)) {
// Path is in format /storage.../Android....
// Get everything before /Android
externalSdCardPath = file.getPath().split("/Android")[0];
break;
}
}
After a lot of research I found a solution. Code at below gives you the path in "SD card/Android/data/your app location " then you can do whatever you want.
getApplicationContext().getExternalCacheDirs()[1]
use getExternalStorageDirectory() instead of getExternalStoragePublicDirectory() like below
Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_DCIM + "/";
or check path first
final String path = android.os.Environment.DIRECTORY_DCIM;
I'm using the access storage framework. I get it by handling the string of uri and get the "3FC5-160A" part and then combine it to the sdcard path.
You can check my detailed answer here
https://stackoverflow.com/a/38648200/6530106
Related
I have write a code to find if SD card path if available which is like this
File[] paths = ContextCompat.getExternalFilesDirs(context, null);
if (paths.length > 1) {
if (paths[1] != null) {
root = paths[1].getAbsolutePath();
// for sd card
} else {
root = Environment.getExternalStorageDirectory().toString();
}
} else {
root = paths[0].getAbsolutePath();
}
I am saving my data in path "/storage/4130-1912/Android/data/com.enable/files" but I wanted to save data outside Android folder.
I have also tried to make an directory outside the Android folder.But unable to make it.I am testing in Lave phone with version Marhmallow
As you are using Marshmallow, you should be requesting runtime permissions (more details here). Despite that, you may add the WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE for external storage access. You can find more information on how to here.
You can access the external storage path like this: Environment.getExternalStorageDirectory().getAbsoluteFile(). If you are getting FileNotFoundException, it's probably because you didn't add an additional "/" before your file. Example:
File file = new File(Environment.getExternalStorageDirectory().getAbsoluteFile() +
"/your_file.txt");
I am saving my data in path "/storage/4130-1912/Android/data/com.enable/files"
Ok. Go ahead. You will succeed.
but I wanted to save data outside Android folder.
Well that is not possible anymore on modern Android systems.
Even inside the Android folder you can only write to mentioned private directory for your app.
If you want to write to the whole micro SD card then use the storage access framework.
This will help you
As miguelarc said:
As you are using Marshmallow, you should be requesting runtime
permissions (more details here). Despite that, you may add the
WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE for external
storage access.
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getPackageName() + "/yourdir");
if (f.mkdirs() || f.isDirectory())
Log.e("path",f.getPath());
//do what you want
}
I am trying to create a folder and then after that do some file IO operations!
I am using a sony Xperia Z to test this out!
I know right now I've hardcoded the location but it doesn't let me create folders!
File appPath = new File("/storage/sdcard1/folder");
if (!appPath.exists()) {
appPath.mkdirs();
}
I am using a targetSdkVersion of 22
And having lollipop on my phone.
I tried
appPath.mkDir();
as well but all this gives a value of False.
And i have added permissions to manifest
<uses-permission name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission name="android.permission.READ_EXTERNAL_STORAGE" />
And I tried many different open source file manager but none are able to create folders, But ES file Manager is able to create folders and do File IO operations!
Don't hardcode global paths like /sdcard, use Environment.getExternalStorageDirectory() and related methods instead. Here is a working sample.
public static String getNewFolderPath() {
File folder = new File(Environment.getExternalStorageDirectory()
.toString() + File.separator + "folder");
if (!folder.exists())
folder.mkdirs();
return folder.getAbsolutePath();
}
EDIT:
For more info check:
Find an external SD card location
#CommonsWare Answer
#Aleadam Answer
Hope it helps!
I am new to android development and I have tried to read a directory from my sd card but didn't got succeeded. Below is the code which I wrote to achieve it
File sdcard = Environment.getExternalStorageDirectory();
if(sdcard.exists()) {
Log.d("Sd card", "Sd card exist");
File[] file_names = sdcard.listFiles();
for(File x : file_names) {
Log.d("File Name",x.getName());
}
}
Control passed the if condition and then I got an NullPointerException at "for each" loop line. Probably function sdcard.listFiles() is returning null. I have an Sd card with many folders and files. Actually I have to create a directory file object for directory "Attachments" which is available on my sd card. I also tried the following code to achieve the same.
File file = new File(android.os.Environment.getExternalStorageDirectory() + File.separator + "Attachments");
and
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "Attachments");
on both code when I called the function file.exists(), it returned false.
I have also checked whether sd card is mounted or not by the following code.
String sdCardAvail = Environment.getExternalStorageState();
if(sdCardAvail.equals(Environment.MEDIA_MOUNTED))
Log.d("Card status", "Sd card Available");
The above code has printed "Sd card Available" at log cat.
So please help me out to know whether I am doing it correct or missing any thing.
Thanks....
In order to read or write files on the external storage, your app must acquire the READ_EXTERNAL_STORAGEorWRITE_EXTERNAL_STORAGE system permissions. For example:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
If you need to both read and write files, then you need to request only the WRITE_EXTERNAL_STORAGE permission, because it implicitly requires read access as well.
Also See This Documentation. It Will solve all your future regarding Storage problems.
i have given required permission :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
hard-coded the path as "/sdcard/filename".
I guess Nexus don't have external SD support but S2 has, that I think might cause a problem in getting the path. How should I handle such a case gracefully?
On each Android Device you can get the path to the external storage like this
Environment.getExternalStorageDirectory()
I've a Nexus device and it works - also on my old milestone
Here is an example usage to create your own apps directory:
You should always check to see if the SDcard is available first because it could be mounted/teathered to a computer or be removed from the device.
private void SetDirectory() {
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File dbDirectory = new File(extStorageDirectory + "/yourAppName/whatever/");
myDirectory.mkdirs();// Have the object build the directory
} else if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED_READ_ONLY)) {
//TODO Make some kind of allert or Toast to warn/notify the user that the SDcard is needed.
}
}
You can use the android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED) method to check if the card is available anywhere within your application.
I have a Samsung Nexus S device with android 4.0 loaded on it. I am trying to create a file in an existing folder on sdcard and get a "permission denied". In the following code, exists() returns true but canWrite() returns false. Why?
File exst = Environment.getExternalStorageDirectory();
String exstPath = exst.getPath();
File d = new File(exstPath+"/TestDir/");
if (!d.exists())
{
int b = 1;
}
if (!d.canWrite())
{
int a = 1;
}
By the way, I've added <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> to the manifest but that did not help.
Is your phone plugged into your computer? If so, the computer will take control of the SD card and not allow it to be written to. Try changing the connection mode to 'Charge Only' if this is the case.
Append getAbsolutePath() to your first line, then it should work:
File exst = Environment.getExternalStorageDirectory().getAbsolutePath();
Update:
Reviewing my own code and other SO answers, I believe you do not use canWrite to check if a path is writable on a SD card. Instead you use Environment.MEDIA_MOUNTED:
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
Log.d("Test", "sdcard mounted and writable");
}
else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
Log.d("Test", "sdcard mounted readonly");
}
else {
Log.d("Test", "sdcard state: " + state);
}
Although all the answers give partial suggestions, the problem is very likely Samsungs non-standard implementation of the API
String myPath = Environment.getExternalStorageDirectory().getAbsolutePath ;
// or .getName() or .getPath() <-- these don't return everything you need.
// same is true for the file version you're trying.
// you have to append
"/external_sd/"
to the path before the file name.
Here's Samsungs explanation for their "breaking" of the API
http://developer.samsung.com/forum/board/thread/view.do?boardName=GeneralB&messageId=162934&messageNumber=1381&startId=zzzzz~&searchType=TITLE&searchText=sdcard
it's also mentioned in several SO posts, but I don't have the links handy...
H
[Edit Mid May, 2013] Here's the pathology of this problem: you can get the path() by the various normal methods mentioned. Then, just write a simple file and watch it show up in the DDMS file explorer. Try hardcoding that exact path and file name OR use the /external_sd/ thing - in both cases, you will not be able to read your own file back in ! (Or you might, but it will contain garbage.) We've verified this on three different S3 phones. Will test more on Samsungs "real" phones via their RemoteTestingLab site and report back.