how to differentiate between internal and external SD card path in android - 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 );

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.

Getting sd card directory in Android device

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. :)

Can't check if file on sdcard exists

I'm trying to make a simple check if the file exist. I saw similar questions here, but they didn't help. When I run my application, the app crashes and I got message "Unfortunatelly, fileCheck1 has stopped". I got this error both on emulator and smartphone.
My code:
package com.example.fileCheck1;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;
import java.io.File;
public class MyActivity extends Activity {
TextView msgText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
msgText = (TextView) findViewById(R.id.textView);
String Path = Environment.getExternalStorageDirectory().getPath()+"/ping.xml";
File file = getBaseContext().getFileStreamPath(Path);
if(file.exists()){
msgText.setText("Found");
}
if(!file.exists()){
msgText.setText("Not Found");
}
}
}
In my Manifest such permissions:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Thanks in advance.
I think that problem is here:
getBaseContext()
where it is assigned to NULL. You really don't need this line. You can simply achieve your goal with
String path = Environment.getExternalStorageDirectory().getPath() + "/ping.xml";
File f = new File(path);
if (f.exists()) {
// do your stuff
}
else {
// do your stuff
}
Update:
If you or someone else have Samsung Galaxy S3, please follow #Raghunandan's answer because in this case getExternalStorageDirectory() returns internal memory.
I have samsung galaxy s3 with android 4.1.2. My internal phone memory is named sdcard0 and my external card extSdCard.
Environment.getExternalStorageDirectory()
So the above returns the path of sdcard0 which is internal phone memory
So get the actual path you can use the below
String externalpath = new String();
String internalpath = new String();
public void getExternalMounts() {
Runtime runtime = Runtime.getRuntime();
try
{
Process proc = runtime.exec("mount");
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
String line;
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
if (line.contains("secure")) continue;
if (line.contains("asec")) continue;
if (line.contains("fat")) {//external card
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
externalpath = externalpath.concat("*" + columns[1] + "\n");
}
}
else if (line.contains("fuse")) {//internal storage
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
internalpath = internalpath.concat(columns[1] + "\n");
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("Path of sd card external............"+externalpath);
System.out.println("Path of internal memory............"+internalpath);
}
Once you get the path
File file = new File(internalpath+"/ping.xml");// internalpath or external path
if(file.exists()){
msgText.setText("Found");
}
else{
msgText.setText("Not Found");
}
UPDATE :
The above solution is not recommended. May not work well. Environment.getExternalStorageDirectory() will always return the path of External Storage. In most cases it is a Sdcard.
From the docs
public static File getExternalStorageDirectory ()
Added in API level 1 Return the primary external storage directory.
This directory may not currently be accessible if it has been mounted
by the user on their computer, has been removed from the device, or
some other problem has happened. You can determine its current state
with getExternalStorageState().
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.
check this:
File file = new File(Environment.getExternalStorageDirectory()+"/ping.xml");
if(file.exists()){
msgText.setText("Found");
}
else{
msgText.setText("Not Found");
}

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