Some android devices has built-in flash memory, and we can check this memory at Environment.getExternalStorageDirectory(). But, when we insert an SD card, then the system differentiates these two with /storage/sdcard0 and /storage/sdcard1.
I am not sure whether /storage/sdcard0 is flash memory or SD card memory. Could anyone provide any explanation as to which is which?
Use the method Environment.isExternalStorageRemovable() to determine if it's a removable SD card or not.
Edit for clarification:
Consider the following method:
public enum ExternalStorageStatus {
READ_WRITE , READ_ONLY, NONE
}
public static ExternalStorageStatus checkExternalStorageStateAvailable(){
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return ExternalStorageStatus.READ_WRITE;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return ExternalStorageStatus.READ_ONLY;
} else {
return ExternalStorageStatus.NONE;
}
}
The method Environment.getExternalStorageState() returns the current state of your storage. If no REAL external storage (i.e. a medium in which isExternalStorageRemoveable() == false), then this returns the current state of your internal storage. If isExternalStorageRemoveable() == true, then getExternalStorageState() returns the state of your removable SD card.
Actual external storage is prioritized.
Related
We have looked at numerous SO post that deal with the SD CARD also the SO post which seems to be the Gold Standard Gold Standard But it deals with permissions we are not asking about permission. The question deals with finding another way to determine if the SD CARD is mounted. This question only wants to deal with SDK 23+ The article that discuss FUSE is at this link FUSE
We have tried this code that when the emulator has the SD CARD ejected returns or evaluates to TRUE. Other similar configuration from SO have also been tested.
My question is not only how to detect if the SD CARD is mounted but why is this code failing? We are not sure if this code can be tested on an emulator or if a real device is needed. We feel this code failure is because of the concept of the term EXTERNAL storage not meaning an actual SD CARD but making reference to the secondary EXTERNAL storage that is internal.
public boolean chkFORSDCARD() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
System.out.println("#################### IS ####### TRUE "+state);
return true;
}
System.out.println("##################### IS ###### Not Available "+state);
return false;
}
Here is where #james_duh are getting into trouble this line of code as mentioned in your comment `THE_PATH = THE_PATH + "/Documents/"; will not work when the SD CARD is unmounted with this line of code set to [1]
File removable = ContextCompat.getExternalFilesDirs(this, null)[1];
The solution is simple remove the THE_PATH = THE_PATH + "/Documents/";
As for testing if the SD CARD is mounted I am still working on that stay tuned
This code is not real neat but it works. Why you want it to work might be a 64K question ? ? I have tested the code and it works. What might be or concern is the words used to evaluate the path not sure they are or will remain consistent
Here is the code It seems point less to check the state so you can remove that test and construct a new more suitable one I did not get that far
public void onAvail() {
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED) || (!state.equals(Environment.MEDIA_MOUNTED_READ_ONLY))) {
File removable = ContextCompat.getExternalFilesDirs(this, null)[1];
THE_PATH = String.valueOf(removable);
if(THE_PATH.contains("Android")){
System.out.println("################################### EXTERNAL Storage "+THE_PATH);
THE_PATH = THE_PATH + "/Documents/";
}else {
File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
String INTERNAL_PATH = String.valueOf(dir);
if(INTERNAL_PATH.contains("emulated")){
System.out.println("######################## $$$$$$$ #### Internal Storage "+INTERNAL_PATH);
}
}
}
}
i am creating Download Manager app therefore my requirement is to store files on sdcard and phone internal storage if sdcard not available and access them later to open files from app.
i have read almost every post to store files but it confuses me to decide which method is best to use because there are lot of different ways to do.i want to create folder inside external(if available) or internal then store files inside this folder.
Now here can anyone tell me what is best way to access sdcard if available otherwise internal storage
Storage options in android is the place where you need to go. You will know how to Checking media availability from there, more specifically external storage.
The sample code is
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
Use Environment to access ExternalStorageDirectory
I use the following code to check if the SD card is available but on a Samsung Galaxy II and Note devices that run Android 4.x and later the OS simulate having a SD card even if in reality there is no SD card on the device.
private boolean isSDCardAvailable() {
return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
}
If SD card is available I then call getExternalCacheDir() get the directory else I display erro r to the user and call getCacheDir() to use internal storage.
The method above return TRUE and ALL devices even if they don't have a SD card.
see this method is available since API level 11, which let you know if Internal Memory working as External storage. in some devices getExternalStorageDirectory() returns true even if SD-Card is not available. read below docs for details.
public static boolean isExternalStorageEmulated ()
Added in API level 11
Returns whether the device has an external storage device which is emulated. If true, the device does not have real external storage, and the directory returned by getExternalStorageDirectory() will be allocated using a portion of the internal storage system.
Certain system services, such as the package manager, use this to determine where to install an application.
Emulated external storage may also be encrypted - see setStorageEncryption(android.content.ComponentName, boolean) for additional details.
Android docs
boolean mExternalStorageAvailable;
boolean mExternalStorageWriteable;
private void checkExternalMedia() {
mExternalStorageAvailable = false;
mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
}
I am facing a problem while trying to write a files into External SD Card in android 4.0.3,even I have made use of the write permissions like WRITE_EXTERNAL_STORAGE & WRITE_MEDIA_STORAGE, So I have found another way to work on it, but now I want to find out whether my app is possible to write into the Removable SD Card
or not, if not then I would like to switch to Internal SD Card.
So now the question is how will I come to know whether writing into Removable SD Card supported or not, So if anyone has done any similar kind of an implementation please feel free to share the code here.
Answer directly from the API guide:
http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
I have an app that writes to both the internal and external SD cards. I have the WRITE_EXTERNAL_STORAGE permission, but nothing else.
The main problem in dealing with the external SD card is to find the path, because getExternalStorageDirectory() usually returns the internal one. It should be a subdirectory of /mnt, if that helps.
To find if you can write to SD card take a look at the Environment class.
String externalStorageState = Environment.getExternalStorageState();
you can then check this state using
Environment.MEDIA_MOUNTED(externalStorageState) and/or Environment.MEDIA_MOUNTED_READ_ONLY(externalStorageState)
Using the api logic you can detect if the sd card is available for read or write, but it doesn't tell you why it is not writable.
I want to know if the user even has a sd card vs if it just mounted.
Is this possible?
for example:
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
}
Check out the possible constants at : http://developer.android.com/reference/android/os/Environment.html#getExternalStorageState%28%29
public static boolean isSdPresent() {
return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
}