Getting sd card directory in Android device - android

Below is the code written for retrieving the sd card directory.
I have been using execution of command and changed into reading the /proc/mounts.
My Question is whether it is the right code ?
Not an expert on Linux OS. Will the /proc/mounts path be same for all the devices ?
I think this code will be also free of any command injection possiblities.
// Process process = new ProcessBuilder().command("mount").start();
// process.waitFor();
reader = new BufferedReader(new FileReader("/proc/mounts"));
String line;
while ((line = reader.readLine()) != null) {
// Output the line of output from the mount command
logger.debug(" {}", line);
if (line.startsWith("/dev/block/vold/")) {
String[] tokens = line.split(" ");
if (tokens.length >= 3 && (tokens[2].equals("vfat") || tokens[2].equals("exfat"))) {
String path = tokens[1];
File file = new File(path);
if (file.exists() && file.isDirectory()) {
logger.debug("Detected SD card at {}", file.getPath());
if (!file.canWrite()) {
logger.warn("The SD card path {} is reporting that it is not writable", file.getPath());
}
return path;
}
}
}
}
cheers,
Saurav

On Android you can get the sd card's directory on any device through
Environment.getExternalStorageDirectory();
http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()

Please use
Environment.getExternalStorageDirectory(); to get the path to SD card.
Also, use Environment.getExternalStorageState() against attribute Environment.MEDIA_MOUNTED etc, to check if the SD card is Readable, Mounted etc. :)

Related

Get the public/root directory of a secondary external storage device in Android?

In android I am able to get my phone's removable external storage by use of:
for (File f : context.getExternalFilesDirs("/"))
if (Environment.isExternalStorageRemovable(f))
Log.println(Log.DEBUG, "#", f.getAbsolutePath());
However, this returns /storage/8E6A-06FF/Android/data/test.application/files which isn't what I want as I simply want the removable's root path /storage/8E6A-06FF/. How can I can get the root path of my phone's removable storage?
You can try this one it is works perfectly for me.It works like a charm with all Os's version.I didn't found any issue so far with this function.
public static String getSDPath() {
String filepath = "";
String[] strPath = {"/storage/sdcard1", "/storage/extsdcard",
"/storage/sdcard0/external_sdcard", "/mnt/extsdcard",
"/mnt/sdcard/external_sd", "/mnt/external_sd",
"/mnt/media_rw/sdcard1", "/removable/microsd", "/mnt/emmc",
"/storage/external_SD", "/storage/ext_sd",
"/storage/removable/sdcard1", "/data/sdext", "/data/sdext2",
"/data/sdext3", "/data/sdext4", "/emmc", "/sdcard/sd",
"/mnt/sdcard/bpemmctest", "/mnt/sdcard/_ExternalSD",
"/mnt/sdcard-ext", "/mnt/Removable/MicroSD",
"/Removable/MicroSD", "/mnt/external1", "/mnt/extSdCard",
"/mnt/extsd", "/mnt/usb_storage", "/mnt/extSdCard",
"/mnt/UsbDriveA", "/mnt/UsbDriveB"};
for (String value : strPath) {
File f = null;
f = new File(value);
if (f.exists() && f.isDirectory()) {
filepath = value;
break;
}
}
return filepath;
}
Try this:
for (File f : context.getExternalFilesDirs("/"))
if (Environment.isExternalStorageRemovable(f))
Log.println(Log.DEBUG, "#", f.getParentFile().getParentFile().getParentFile().getParent());
context.getExternalFilesDirs() will always returns application-specific directory. But the good thing is that application-specific directories are always 4 level deep from the root folder of the storage device. So calling getParentFile() four times on the File f instead of f.getAbsolutePath() will get you the root path of your phone's removable storage.
Maybe just split it at Android?
I tested it, and it works after I request for permission - WRITE_EXTERNAL_STORAGE.
fun getBaseDir(dir: File): String {
val absPath = dir.absolutePath
return if (absPath.contains("/Android")) {
absPath.split("/Android")[0]
} else {
absPath
}
}
This will loop through files on sdcard root directory. If you want primary storage, just change [1] to [0].
getExternalFilesDirs returns paths to your app directory on primary and secondary storage. After splitting the second path by "Android", the first string will contain path to your secondary storage root. for example in my case it was "/storage/B242-37B2/". Working with minSdkVersion 19+.
String sdCardRoot = ContextCompat.getExternalFilesDirs(getApplicationContext(), null)[1].getAbsolutePath().split("Android")[0];
File f = new File(sdCardRoot);
File[] files = f.listFiles();
for (File inFile : files){
Log.d("Files", inFile.getName());
}
Try this one if it helps you. For more information refer this link.
public static HashSet<String> getExternalMounts() {
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try {
final Process process = new ProcessBuilder().command("mount")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
s = s + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines) {
if (!line.toLowerCase(Locale.US).contains("asec")) {
if (line.matches(reg)) {
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("/"))
if (!part.toLowerCase(Locale.US).contains("vold"))
out.add(part);
}
}
}
}
return out;
}
Here is another approach for the same. Source from here.
Environment.getExternalStorageState() returns path to internal SD
mount point like "/mnt/sdcard"
But the question is about external SD. How to get a path like "/mnt/sdcard/external_sd" (it may differ from device to device)?
Android has no concept of "external SD", aside from external storage, as described above.
If a device manufacturer has elected to have external storage be on-board flash and also has an SD card, you will need to contact that manufacturer to determine whether or not you can use the SD card (not guaranteed) and what the rules are for using it, such as what path to use for it.

Sd Card Path of Android Phone

I am trying to make a file browser app. So I want to begin with displaying something like this.
But I can not reach my SD card's path. I used this method
String path = Environment.getExternalStorageDirectory();
In the documentation here It says:
Note: don't be confused by the word "external" here. This directory can better be thought as media/shared storage. It is a filesystem that can hold a relatively large amount of data and that is shared across all applications (does not enforce permissions). Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected internal storage and can be mounted as a filesystem on a computer.
The problem is I can reach to the device storage but I can't reach to my SD card's path. Does anyone know how to get that path?
// Access the built-in SD card
private String getInnerSDCardPath() {
return Environment.getExternalStorageDirectory().getPath();
}
// Access to external SD card
private List<String> getExtSDCardPath() {
List<String> pathList = new ArrayList<String>();
try {
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("mount");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
if (line.contains("extSdCard")) {
String[] arr = line.split(" ");
String path = arr[1];
File file = new File(path);
if (file.isDirectory()) {
pathList.add(path);
}
}
}
bufferedReader.close();
} catch (Exception e) {
e.printStackTrace();
}
return pathList;
}
I hope it can help you.

Not able to write to app specific directory in Android SD card

I learnt that from KitKat an application can only write to its specific directory.
But strangely i am not able to write into my specific application directory also.
Code to get the sd card directory
Process process = new ProcessBuilder().command("mount").start();
process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
// Output the line of output from the mount command
logger.debug(" {}", line);
if (line.startsWith("/dev/block/vold/")) {
String[] tokens = line.split(" ");
if (tokens.length >= 3 && (tokens[2].equals("vfat") || tokens[2].equals("exfat"))) {
String path = tokens[1];
File file = new File(path);
if (file.exists() && file.isDirectory()) {
logger.debug("Detected SD card at {}", file.getPath());
if (!file.canWrite()) {
logger.warn("The SD card path {} is reporting that it is not writable", file.getPath());
}
// path = basecontext.getExternalFilesDir(null).getPath();
return path;
}
}
}
}
Code to get a file
Here is how i construct the file path :
sdCardDirectory is the directory which i get like this: /storage/extSdCard/
directory and sub directory are my application sepcifc subdirectoryies but are obviously inside the app specific directory in the application
sdCardDirectory + File.separator + "Android" + File.separator + "data" + File.separator
+ <my app package> + File.separator + subdirectory
+ File.separator + directory+ File.separator + document.getRepositoryId() + FILENAME_SEPARATOR
+ fetchObjectId(document);
Where the ids retrieved are simple alpha numeric strings for e.g. aBc45ef_0
randomAccessFile = new RandomAccessFile(file, "rw");
I am getting
java.io.FileNotFoundException: /storage/extSdCard/Android/data/myapp/cache/downloaded/OhCQL_RQl8IJcVlO5T1MX4-3SQg_mMDT5PWtf-IYmE0: open failed: EROFS (Read-only file system)
Where myapp is the my application package name.
UPDATE This is the link to Android bug which i have opened https://code.google.com/p/android/issues/detail?id=69549&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars
cheers,
Saurav
But strangely i am not able to write into my specific application directory also.
That code is not necessarily going to give you anything that you can use. Please use getExternalFilesDirs() (note the plural); the second and subsequent entries in the returned list will be from removable storage, where available.
You may wish to read my blog post on Android 4.4 and removable storage for more background.

how to differentiate between internal and external SD card path in android

In android application I need to do:
If(removable SdCard is present){
String path=get the path of removable Sdcard() ;
//using this path we will create some files in sdcard
} else{
//display error message
}
To achieve this we used the code as:
If (Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)){
String path= Environment.getExternalStorageDirectory().getPath();
}
The above code fails in some of latest android mobiles. Please help us on this.
Below are the details of what we have tried:
In android mobiles having OS of ICS and JellyBean, the exact path of the removable sdcard varies because of device manufacturer.
See the table below
Tested Devices OS version removable sdcard path internal sd path
Samsung galaxy s2 4.0.4 /mnt/sdcard/external_sd /mnt/sdcard
Samsung S Advance 4.1.2 /storage/extSdCard /storage/sdcard0
Samsung Galaxy s3 4.0.4 /mnt/extSdCard /mnt/sdcard
Samsung Galaxy Note 4.0.4 /mnt/sdcard/external_sd /mnt/sdcard
When running the above code in these devices we got:
The android API Environment.getExternalStorageDirectory().getPath() returns only the internal sd path
Also the the API Environment.getExternalStorageState() return Environment.MEDIA_MOUNTED in above devices even though sdcard is removed.
Further the API Environment.isExternalStorageRemovable() always returns false for above devices whether removable sdcard is present or not.
We searched in google and tried some functions they given.It gives only list of storage paths that are mounted to the device.But it doesnot indicate whether the removale sdcard is present or not.
The function i tried to get the storage path:
private static String getMountedPaths(){
String sdcardPath = "";
Runtime runtime = Runtime.getRuntime();
Process proc = null;
try {
proc = runtime.exec("mount");
} catch (IOException e1) {
e1.printStackTrace();
}
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
String line;
BufferedReader br = new BufferedReader(isr);
try {
while ((line = br.readLine()) != null) {
if (line.contains("secure")) continue;
if (line.contains("asec")) continue;
if (line.contains("fat")) {//TF card
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
mount.add(columns[1]);
sdcardPath=columns[1];
}
} else if (line.contains("fuse")) {//internal storage
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
mount.add(columns[1]);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return sdcardPath;
}
Is there any other function better than above to get the list of storage paths in android ?
also help to solve the above problem .
To get internal SD card
String internalStorage = System.getenv("EXTERNAL_STORAGE");
File f_exts = new File(internalStorage );
To get external SD card
String externalStorage = System.getenv("SECONDARY_STORAGE");
File f_secs = new File(externalStorage );

Accessing USB Pendrive from android tablet

We have a usb port in our android tablet(version 4.0.3).
How do we find out any PenDrive connected on that port or not.
How do we access the files in the USB Pendrive which connected on that port through programmatically in android.
We have a /mnt contained Folder as
asec
extsd
obb
sdcard
secure
usbhost1
How to programmatically identify which one is Internal Memory Path, External SD Card Path and USB Path.
What is the purpose for used this folder asec, obb and secure.
Thanks in advance.
Regards
Bala
I guess to use the external sdcard you need to use this:
new File("/mnt/external_sd/")
OR
new File("/mnt/extSdCard/")
OR
new File("/mnt/usb_storage")
in replace of Environment.getExternalStorageDirectory()
Works for me. You should check whats in the directory mnt first and work from there..
You should use some type of selection method to choose which sdcard to use:
File storageDir = new File("/mnt/");
if(storageDir.isDirectory()){
String[] dirList = storageDir.list();
//TODO some type of selecton method?
}
The "pen drive" is located in /mnt/ (just like all other storage devices in 4.0>)
It will probably be different for some devices, for the Acer Iconia A500 running 4.0.3 usb storage is under /mnt/usb_storage/
How do we find out any PenDrive connected on that port or not.
There is no documented and supported means to do that in the Android SDK. You would need to speak with your device manufacturer and get their recommendations for how to do this for their specific device.
How do we access the files in the USB Pendrive which connected on that port through programmatically in android.
See above.
*Using this you can find path and asses the file in USB*
public String getStoragepath() {
try {
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("mount");
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
String line;
String[] patharray = new String[10];
int i = 0;
int available = 0;
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
String mount = new String();
if (line.contains("secure"))
continue;
if (line.contains("asec"))
continue;
if (line.contains("fat")) {// TF card
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
mount = mount.concat(columns[1] + "/requiredfiles");
patharray[i] = mount;
i++;
// check directory is exist or not
File dir = new File(mount);
if (dir.exists() && dir.isDirectory()) {
// do something here
// t1.show();
available = 1;
finalpath = mount;
break;
} else {
}
}
}
}
if (available == 1) {
} else if (available == 0) {
finalpath = patharray[0];
}
} catch (Exception e) {
}
return finalpath;
}

Categories

Resources