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;
}
}
Related
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
In my app, im trying to check whether the user has connected their phone to the pc as a drive, so I can warn them to disconnect it because I need access to the storage.
It works fine on all 4-5 devices that I've tested on, except this HTC Desire X phone, Android 4.0.4 . It has no SD card, but there is about 2 gb of some storage available for writing.
Here is the code that I use
private void checkStorage() {
// Get the external storage's state
String state = Environment.getExternalStorageState();
Log.d("STATE", state);
if (state.equals(Environment.MEDIA_MOUNTED)) {
// Storage is available and writeable
externalStorageAvailable = externalStorageWriteable = true;
} else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
// Storage is only readable
externalStorageAvailable = true;
externalStorageWriteable = false;
} else {
// Storage is neither readable nor writeable
externalStorageAvailable = externalStorageWriteable = false;
}
}
So when I run it, the logcat debug tag returns:
removed
According to documentation:
http://developer.android.com/reference/android/os/Environment.html#MEDIA_REMOVED
"Storage state if the media is not present."
How can I modify this code so it detects the presence of a memory that is available for use?
Now, there is another thing. On this phone, when I try downloading an image from the browser, Im not allowed to, and I get the following message:
No SD card
An SD card is required to download <filename>
OK
Is there something wrong with the phone or is this normal? How do I make my app work on this phone?
EDIT: Furthermore, if I am able to get past this, how do I write files to the storage? Here's my code that does that and works on other devices:
File directory = null;
File file = null;
try {
directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),
Utils.getWritableDiectory(Locale.ENGLISH));
if (!directory.exists()) {
directory.mkdirs();
}
file = new File(directory, "data.json");
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.
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)
My application uses a data directory on the SD card to store files. At startup, it creates this directory if it isn't already present. For some reason this works on the different AVDs I have set up, except that I can't get it to work if I set the resolution to QVGA.
The code is boring:
File root = new File("/sdcard/mydir");
if(!root.exists()) {
try {
root.mkdir();
}
catch...
mkdir() is returning false.
Any ideas why?
It's possible that you forgot to set up the SD card when creating the QVGA AVD. Try setting it up again.
Also, you should not be hard coding path to external storage. http://developer.android.com/guide/topics/data/data-storage.html explains some of the APIs to access external storage.
The following snippet might detect some issues with mounting.
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;
}
It turns out that I had forgotten to add the SD card permission to my manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Without the permission the program worked on all emulators except QVGA, and even on my Droid.