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.
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
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");
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)