In my android application, I am trying to create the following folder on the sdcard:
/mnt/sdcard/OSGiComponents/admin/felix-cache/
Here's the code:
File cacheDir =
new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache/" );
// Create the folder
cacheDir.mkdirs();
// Check if it exists
if ( ! cacheDir.exists() ) {
Log.e ( "Debug" , "Cache directory cannot be created" );
}
I have the WRITE_STORAGE_PERMISSION under the manifest tag of the android manifest file. I am able to create other folders and files without problem on the sdcard.
The app works fine on the following phones:
Nexus S (rooted) running Gingerbread (2.3)
Nexus S (unrooted) running Jelly Bean (4.1.2)
HTC Desire (rooted) running Froyo (2.2)
HTC Desire (unrooted) running Froyo (2.2)
However on Samsung Galaxy Nexus phone (unrooted) running Ice Cream Sandwich (4.0.4), the directory is created as a zero size file, which can be seen in Astro. The exists() call returns false.
As you can see from the folder name, I am using Apache Felix. Felix creates the cache directory automatically if it does not exist. On Galaxy Nexus, it always complained that it is unable to create the cache directory. Astro shows a 0 byte file instead of a folder. This is why I decided to try creating the cache folder myself before initializing Felix.
So, I create the cache folder myself. The app works fine the first time, and I can see the folder fine in Astro. If I close the app, then delete the folder in Astro, and then re-launch the app, even my code mysteriously cannot create the cache directory, and Astro shows a 0 byte file.
The 0 byte file cannot be deleted in Astro. However, when I reboot the phone, the folder is magically there and ok.
I use FileInstall to watch the OSGiComponents/install folder. When I drop bundle jars into that folder, it is detected and installed ok on all phones except Galaxy Nexus (when the app works the first time). There are no logs/errors from FileInstall about not being able to watch the directory.
I have tested this on 2 Galaxy Nexus phones, same problem.
I suspect it is a permissions problem, but I not sure what it is, and why a 0 byte file is created while exists() returns false. Nowhere else in the code am I creating this file.
Any suggestions on what could be the problem?
Thanks :)
UPDATE: I think I have identified the issue, please see the answer I posted.
please use instead of
File cacheDir = new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache/" );
cacheDir.mkdirs();
to
File cacheDir =
new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache" );
cacheDir.mkdir();
I found a workaround which solves this problem. Whenever I am deleting a file/directory, instead of using delete() directly, I rename the file/folder, and then delete() it. This weird workaround seems to remove the problem.
I got this idea by seeing this question's answers - Open failed EBUSY device or Resource busy
However, I'm not sure why this works, or what caused the problem in the first place.
In case anyone else is using Felix on Galaxy Nexus and encounters the same problem, just change the Felix source code as shown below:
org.apache.felix.framework.util.SecureAction.java:
public boolean deleteFile(File target)
{
if (System.getSecurityManager() != null)
{
try
{
Actions actions = (Actions) m_actions.get();
actions.set(Actions.DELETE_FILE_ACTION, target);
return ((Boolean) AccessController.doPrivileged(actions, m_acc))
.booleanValue();
}
catch (PrivilegedActionException ex)
{
throw (RuntimeException) ex.getException();
}
}
else
{
// Solution: Rename before deleting
// https://stackoverflow.com/questions/11539657/open-failed-ebusy-device-or-resource-busy
File to = new File(target.getAbsolutePath() + System.currentTimeMillis());
boolean renameStatus = target.renameTo(to);
boolean deleteStatus = to.delete();
boolean returnStatus = ( renameStatus && deleteStatus );
// Debug SecureAction
//boolean returnStatus = target.delete();
Log.e ( "SecureAction" , "Deleting " + target + " delete(): " + returnStatus );
return returnStatus;
}
}
I suggest that you connect to the device using adb and use the command ls -l in the directory, to check what is operating system reporting about this 0 size file (permissions, etc.). This can eventually bring some light to the issue.
If you can't figure out a working solution, maybe you can make a workarround using the exec() to execute a mkdir directly.
You can use the cobe bellow to do it:
public static boolean execCmd(String command, ArrayList<String> results){
Process process;
try {
process = Runtime.getRuntime().exec(new String [] {"sh", "-c", command});
} catch (IOException e) {
e.printStackTrace();
return false;
}
int result;
try {
result = process.waitFor();
} catch (InterruptedException e1) {
e1.printStackTrace();
return false;
}
if(result != 0){ //error executing command
Log.d("execCmd", "result code : " + result);
String line;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
try {
while ((line = bufferedReader.readLine()) != null){
if(results != null) results.add(line);
Log.d("execCmd", "Error: " + line);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return false;
}
//Command execution is OK
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
try {
while ((line = bufferedReader.readLine()) != null){
if(results != null) results.add(line);
Log.d("execCmd", line);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
To use it:
boolean res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents", results);
if(!res) return error;
res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents/admin", results);
if(!res) return error;
res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents/admin/felix-cache", results);
if(!res) return error;
Regards.
String root = Environment.getExternalStorageDirectory()
.getAbsolutePath()+"/OSGiComponents/admin/felix-cache";
File myDir = new File(root);
String fname = "Image Name as you want";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Although not a direct answer to your question,the information mentioned below may help you:
In certain devices, the Environment.getExternalStorageDirectory().getAbsolutePath() does not necessary reflect the actual external sd card path. Sometimes it represents the internal storage.
for example in Galaxy Note 2:
Log.i(TAG,Environment.getExternalStorageDirectory().getAbsolutePath());
will print
12-19 17:35:11.366:
E/sample.Examples(10420): /storage/sdcard0
meanwhile the actual external sd card should be:
/storage/extSdCard
The following are several posts regarding to this issues which may help you:
Building a Utility to get the path to External Removable storage every time
Check if the SDCard is present, boolean is always true
How could i get the correct external storage on Samsung and all other devices?
Android how to use Environment.getExternalStorageDirectory()
Related
I have a directory structure of files in external storage. They don't show up in the Android File Transfer app, so I think it's a media scanner problem.
I'm creating them with a FileOutputStream in a directory based on Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).
I have the following method, called from an activity, so context is an activity (forget that this blocks the main thread for now!):
public void scan(Context context, File base) {
File[] files = base.listFiles();
if (files == null) {
return;
} else {
for (File file : files) {
if (file.isFile()) {
String path = file.getAbsolutePath();
MediaScannerConnection.scanFile(context, new String[]{path}, null, null);
Log.e("Langstroth", path);
} else if (file.isDirectory()) {
this.scan(context, file);
}
}
}
}
public void scan(Context context) {
this.scan(context, this.baseDir);
}
}
The output of the log is as expected:
E/MyApp﹕ /storage/emulated/0/Documents/Langstroth/sample/5000/1430576404874.wav
E/MyApp﹕ /storage/emulated/0/Documents/Langstroth/sample/5000/1430577209491.wav
And then lots of:
E/MyApp﹕ Scan completed path /storage/emulated/0/Documents/Langstroth/sample/5000/1430576404874.wav uri content://media/external/audio/media/7836
E/MyApp﹕ Scan completed path /storage/emulated/0/Documents/Langstroth/sample/5000/1430577209491.wav uri content://media/external/audio/media/7838
This proves that the files exist. They don't show up in the Android File Transfer though.
Here's the strange thing. Another method:
public void otherDemo(Context context, File baseDir) {
String newPath = baseDir.getAbsolutePath() + "/some/random/dirs";
Log.e("Langstroth", "New path " + newPath);
File dir = new File(newPath);
dir.mkdirs();
Log.e("Langstroth", dir.exists() ? "Dir exists": "Dir does not exist");
File f = new File(dir, "myfile.txt");
try {
new BufferedOutputStream(new FileOutputStream(f)).close();
} catch (IOException e) {
e.printStackTrace();
}
Log.e("Langstroth", f.exists() ? "File exists": "File does not exist");
MediaScannerConnection.scanFile(context, new String[]{f.getAbsolutePath()}, null, null);
}
and the log output:
E/MyApp﹕ New path /storage/emulated/0/Documents/Langstroth/some/random/other/dirs
E/MyApp﹕ Dir exists
E/MyApp﹕ File exists
E/MyApp﹕ File: /storage/emulated/0/Documents/Langstroth/some/random/other/dirs/myfile.txt
E/MyApp﹕ Other scan completed path /storage/emulated/0/Documents/Langstroth/some/random/other/dirs/myfile.txt uri content://media/external/file/7842
One test file shows up, the others don't
Proof:
Where are the other files?
Generally speaking, before you let another process work with a file, you want to ensure all bytes are flushed to disk, via getFD().sync(). In particular, this seems to help with the whole media scanning thing.
the files shows up in a .listFiles(), and .exist(), and the callback for the MediaScanner says that it completed correctly. Surely an extant (if empty) file should show up?
The ways of the media scanner are mysterious. :-) IOW, beats me.
Bear in mind that there are multiple moving parts here: your app, the media scanner, the MTP daemon on Android, and your MTP client. The breakdown could be at any stage. If you unplug and re-plug in the device, and now the files show up in your MTP client, my guess would be that the MTP client is working off of a slightly stale cache.
We've just fallen foul of the new permissions that apply to writing files to sd cards (external storage) on Android 4.4 (EACCES Permission Denied)
Prior to KitKat we set our writable folder like this:
mfolder = Environment.getExternalStorageDirectory().getPath() + "/appfiles";
However after hours of searching I've come to the conclusion, rightly or wrongly that on 4.4 devices to enable writing of files this needs to be changed to:
mfolder = Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.xyz.abc/appfiles";
So mfolder would be something like: /mnt/sdcard/Android/data/com.xyz.abc/appfiles
Is this correct, do we create a folder like the one above on the sdcard to enable 4.4 devices to write files?
mfolder is a String that we save to shared preferences.
Then we have this code that runs once if API>=19 that changes the mfolder String and then copies all the files from the old folder to the new 'kitkat' folder.
if (android.os.Build.VERSION.SDK_INT>=19){
if (!mfolder.contains("/Android/data/com.xyz.abc/appfiles")){
if (prefs.getBoolean("kitkatcheck", false)==false){
//update mfolder from
// /mnt/sdcard/appfiles
// to
// /mnt/sdcard/Android/data/com.xyz.abc/appfiles
String prekitkatfolder = mfolder;
String kitkatfolder = mfolder.replace("/appfiles", "/Android/data/com.xyz.abc/appfiles");
mfolder = kitkatfolder;
try {
File sd = new File(mfolder);
if(!sd.exists() || !sd.isDirectory()) {
sd.mkdirs();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), "Error creating Kitkat folder!\n" + e.toString(), Toast.LENGTH_LONG).show();
return;
}
prefEditor.putString("patternfolder", mfolder);
prefEditor.putBoolean("kitkatcheck", true);
prefEditor.commit();
//copy files and folder from old appfiles folder to new.
AllFiles.clear();
listFilesAndFilesSubDirectories(prekitkatfolder);
if (AllFiles.size()>0){
for (File child : AllFiles ) {
try {
File dest = new File(child.toString().replace(prekitkatfolder, kitkatfolder));
try {
String filePath = dest.getPath().substring(0, dest.getPath().lastIndexOf(File.separator));
File subfolder = new File(filePath);
if(!subfolder.exists() || !subfolder.isDirectory()) {
subfolder.mkdirs();
}
} catch (Exception ex) {
}
copyFile(child, dest);
} catch (Throwable t) {
}
}
}
}
}
I then notify the user that their files have been copied to the new folder and that due to the new permissions they would have to manually delete the old prekitkatfolder folder. I guess they will only be able to do this if they have a stock file manager or if they unmounted sd card and place it in a PC, due to the new 4.4 permissions?
Also, for us it appears that these 4.4 permissions are not affecting all our users with Kitkat. Some can still write to the original folder location on their external storage and some get the EACCES (Permission Denied) error. Can anyone throw any light on why this might be, one would think it would apply to all 4.4 devices using external storage?
As we have no actual 4.4 device we are having to test this code using the emulator (API 19) but we do not get the EACCES Permission Denied error. So we released a beta version with code above and have been told that the copied files ended up in internal storage, how can that be?
Any ideas what we're doing wrong, thanks in advance
Updated solution.
This sets and also creates the folder in the correct place for KitKat.
mfolder = this.getExternalFilesDir("asubfoldername").getAbsolutePath();
However, this isn't full-proof, if the Android device has both an internal and external secondary storage locations, the above will use the internal one. Not really what we want as we require path to removable sdcard or better still the path to the secondary storagelocation with the most free available space.
File[] possible_kitkat_mounts = getExternalFilesDirs(null);
Note the "s" on the end of getExternalFilesDirs. This creates an array of secondary external storage locations.
for (int x = 0; x < possible_kitkat_mounts.length; x++) {
//Log.d("test", "possible_kitkat_mounts " + possible_kitkat_mounts[x].toString());
boolean isgood=false;
if (possible_kitkat_mounts[x] != null){
isgood = test_mount(possible_kitkat_mounts[x].toString());
if (isgood==true){
arrMyMounts.add(newymounts(Device_get_device_info(possible_kitkat_mounts[x].toString()), possible_kitkat_mounts[x].toString()));
}
}
}
//sort arrMyMounts size so we can use largest
Collections.sort(arrMyMounts, new Comparator<mymounts>(){
public int compare(mymounts obj1, mymounts obj2){
return (obj1.avaliablesize > obj2.avaliablesize) ? -1: (obj1.avaliablesize > obj2.avaliablesize) ? 1:0 ;
}
});
if (arrMyMounts.size()>0){
mfolder = arrMyMounts.get(0).name + "/asubfoldername";
//Log.d("test", "selected kitkat mount " + kitkatfolder);
}else{
//do something else...
}
From the array of possible_kitkat_mounts we check via test_mount to see if we can actually write to the selected location and if successful we add that location to arrMyMounts.
By sorting arrMyMounts we can then get the location with the most available free space.
Hey presto, arrMyMounts.get(0).name is a kitkat secondary storage location with the most free space.
Google has blocked write access to external storage devices in Android 4.4. Until they change it there is no way to revert it back without root.
More info: https://groups.google.com/forum/#!msg/android-platform/14VUiIgwUjY/UsxMYwu02z0J
It might be working on some devices with Kitkat which have minisd card slot. It is confusing :(
I have a problem with creating a folder and a file on the sdcard.
Here's the code:
File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/folder");
boolean success;
if (!folder.exists()) {
success = folder.mkdirs();
}
File obdt = new File(folder, "file.txt");
try {
success = obdt.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
With this code I expect to create the folderfolder in the Download folder of the sdcard and in this the file file. I want that the user can access the file. So I want to put it in a shared folder.
The success variable is true and when I run the code again the folder already exists and doesnt come in the if-block.
But I can't see the created folder and file on the sdcard in file explorer.
Info:getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() returns storage/sdcard/Download
I work with a Galaxy Nexus.
Damn! :)
Now I solved my problem...I was misunderstanding the operation of creating files in the file system.
When I spoke of file explorer I meant the file explorer of the operating system and NOT the file explorer in the DDMS :).
I thought when I create a file I will see it in the file explorer of the operating system but when the device is connected to the PC the files can only be seen in the DDMS file explorer.
Sorry I'm new to Android ;)
When the App is running standalone without PC connection and afterwards I connect with the PC I see the created files and folders of course :)
Thanks for help
Any errors from logcat?
Else: try something like Log.I("PATHNAME",folder.absolutePath()); and then look in your logcat to make sure where you are creating the folder where you think it is.
If you haven't done so already, you will need to give your app the correct permission to write to the SD Card by adding the line below to your Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
If you have already done that see if :
File obdt = new File(/sdcard/folder/file.txt)
try {
success = obdt.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
works.
You cannot see the folder/file in explorer? Maybe it is because the MediaScanner is active, but not adding your files. You can do this in your program or switch the Media Scanner of somewhere in your phone settings.
MediaScanner
Trigger MediaScanner
Try this out.
File dir = new File(Environment.getExternalStorageDirectory()
+ "/XXX/Wallpapers/");
File[] files = dir.listFiles();
if (files == null)
{
int numberOfImages = 0;
BitmapDrawable drawable = (BitmapDrawable) imageView
.getDrawable();
Bitmap bitmap = drawable.getBitmap();
File sdCardDirectory = Environment
.getExternalStorageDirectory();
new File(sdCardDirectory + "/XXX/Wallpapers/").mkdirs();
File image = new File(sdCardDirectory
+ "/XXX/Wallpapers/Sample" + numberOfImages + ".JPG");
boolean success = false;
FileOutputStream outStream;
try {
outStream = new FileOutputStream(image);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
success = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (success) {
Toast.makeText(
getApplicationContext(),
"Image saved successfully in Sdcard/XXX/Wallpapers",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"Error during image saving", Toast.LENGTH_LONG)
.show();
}
Dont forget to add permission in manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Apparently there is a known bug in MTP.
Issue 195362
All phones using MTP instead of USB Mass storage do not properly show the list of files when that phone is connected to a computer using a USB cable. Android apps running on the device also cannot see these files.
It is actually as old as 2012
I've encountered the same problem: created files and folders don't show immediately after being written to sdcard, despite the file being flushed and closed !!
They don't show on your computer over USB or a file explorer on the phone.
I observed three things:
if the absolute path of the file starts with /storage/emulated/0/ it doesn't mean it'll be on your sdcard - it could be on your main storage instead.
if you wait around 5 minutes, the files do begin to show over USB (i.e. Windows explorer and built-in file explorer)
if you use adb shell ls /sdcard from terminal, then the file does show! you could use adb pull ... to get the file immediately. You could probably use DDMS too.
Code I used was:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(myArrayList);
try {
File externalDir = getExternalStorageDirectory();
File newFile = new File(externalDir, "myfile.txt");
FileOutputStream os = new FileOutputStream(newFile);
os.write(json.getBytes());
os.flush();
os.close();
Timber.i("saved file to %s",newFile.getAbsoluteFile().toString());
}catch (Exception ex)
{
Toast.makeText(getApplicationContext(), "Save to private external storage failed. Error message is " + ex.getMessage(), Toast.LENGTH_LONG).show();
}
and
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(myArrayList);
try {
File externalDir = getExternalStorageDirectory();
File newFile = new File(externalDir, "myfile.txt");
FileWriter fw = new FileWriter(newFile);
fw.write(json);
fw.flush();
fw.close();
Timber.i("saved file to %s",newFile.getAbsoluteFile().toString());
}catch (Exception ex)
{
Toast.makeText(getApplicationContext(), "Save to private external storage failed. Error message is " + ex.getMessage(), Toast.LENGTH_LONG).show();
}
why is it like this? Seems like another one of those "Android-isms" that you have to suffer through the first time you experience it.
The issue I am having could be a hardware-related. In any case I'm stumped.
I have written some code (that I took and modified from: Writing Text File to SD Card fails) I've put the code below. It works fine on my Sony Ericcson X8. However, on the Sony Ericsson Arc, I can't find the file when I look for it on the phone! I went line by line through the code and there are no failures. It's as if it's on the phone and I'm just blind. I can even see in the debugger that the value of gpxfile is:
/mnt/sdcard/MyCompany/MyLog
But when I use windows explorer to look for the file, I certainly don't see the directory MyCompany. Is there some setting on the phone that (silently) prevents writing to the SD Card?
Here is the code:
public static boolean generateNoteOnSD(String sFileName, String sBody) {
try {
String auxSDCardStatus = Environment.getExternalStorageState() ;
if (!auxSDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
Log.i(TAG, "generateNoteOnSD auxSDCardSTatus: " + auxSDCardStatus);
}
if (auxSDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
File root = new File(Environment.getExternalStorageDirectory(), "Dexcom");
if (!root.exists()) {
root.mkdirs();
}
File gpxfile = new File(root, sFileName);
FileWriter writer = new FileWriter(gpxfile, true);
String currentTimeString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
writer.append(currentTimeString + ", " + sBody +System.getProperty("line.separator") );
//writer.newLine();
writer.flush();
writer.close();
Log.d(TAG,"generateNoteOnSD: Saved to file: " + sBody);
return true;
} else {
return false;
}
} catch(IOException e) {
e.printStackTrace();
return false;
//importError = e.getMessage();
//iError();
}
}
In my case the problem was that I had the Xperia ARC attached to the laptop with a USB cable. Apparently, things don't work quite right if you do that. No problem with the X8, so I'm guessing that it's phone specific. Computer may be putting lock on the file thus preventing Android from updating file. Not sure why I don't get an error though.
Bottom line for future readers: Try disconnecting phone from computer.
i have a problem with my code that is supposed to write some data string to my sdcard. i use a class to do this:
public class CVS {
private String path;
private String filename;
private File dir;
private File file;
private FileWriter fw;
public CVS() {
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/traffic/";
filename = "data.cvs";
file = new File(path, filename);
createDir();
}
private void createDir() {
dir = new File(path);
if(!dir.exists()) {
if(file.mkdirs() == false) {
Log.d(Config.LOGTAG, "UHOH!!!!!!!!!!!!!!!!!!!!!!!!");
}
}
else Log.d(Config.LOGTAG, "dir exists");
}
public void writeToFile(String data) {
try {
fw = new FileWriter(file);
fw.append(data); Log.d(Config.LOGTAG, "data saved to file...");
}
catch(Exception e) {
Log.d(Config.LOGTAG, "file: " + e.getMessage());
}
}
}
this results ALWAYS in an exeption being caught in writeToFile(), saying "permission denied". actually, i set permissions to WRITE_EXTERNAL_STORAGE in the manifest. so - what am i doing wrong!?
additional info: real device with sd card mounted. no emulator. android 2.2. if i create the dir myself, the problem wont go away :(
Either:
Your manifest is wrong, or
Your external storage is mounted on your development machine, or
Your manual concatenation of your directory is wrong
Your code is ok but still you can add a check for whether sdcard is inserted or not, if you run this code and sdcard is not inserted then it will throw an exception, good practice is that you should always catch the exeptions.
you can check sdcard by following code...
if (android.os.Environment.getExternalStorageState().equals
(android.os.Environment.MEDIA_MOUNTED))
{
//code or logic if sd card is inserted....
}
else
{
Log.e("Exception","SD Card not found!");
}
All of the answers are needed, but if it's a Samsung device, then you need to append "/external_sd/" to the path - because they decided they needed to dork with our minds and break the API:
"http://developer.samsung.com/forum/board/thread/view.do?boardName=GeneralB&messageId=162934&messageNumber=1381&startId=zzzzz~&searchType=TITLE&searchText=sdcard