Reputation: 2860
EDIT2: For people stumbling across this question from Google. The canWrite()
function is kinda buggy and doesn't seem to work properly. I would recommend not using it. Just catch
and exceptions instead. Also make sure your phone is not in USB Storage
mode so that you can write to the SD card. Lastly make sure the settings in Android device don't have write protection or anything of the sort on.
I seem to be having issues trying to write to my SD card on my Android phone. It doesn't matter if I am in debug mode with Eclipse, or running the phone on it's own. I cannot write to the SD Card. Yes the permissions are configured, as shown below. When using the code snippet provided on the Android site I am being given false for both of the booleans after it finishes the segment. I have absolutely no idea why the storage is not available or writable. I eject the SD card and the phone from my Mac to make sure they are not using it and that the phone can mount, but like I said I get the same issue when not using Eclipse at all.
EDIT: Using a real Android phone running 4.04 according to the about information.
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;
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tinywebteam.gpstracker"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.tinywebteam.gpstracker.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
It fails when trying to execute mkdirs()
below and throws the assigned exception:
try {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/GPStracker/data/");
if (!dir.exists()) {
if (!dir.mkdirs())
throw new FileNotFoundException("Couldn't make directory.");
}
File fileOut = new File(dir, "GPSTracker_" + ts + ".csv");
if (fileOut.canWrite()) {
FileOutputStream out = new FileOutputStream(fileOut);
out.write(fileStr.getBytes());
out.close();
System.out.println("File written successfully");
} else {
System.out.println("Could not write to file");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Upvotes: 3
Views: 13462
Reputation: 5578
According to the documentation, the state you're describing means that the external media storage isn't accessible to you:
public static final String MEDIA_SHARED
Added in API level 1 getExternalStorageState() returns MEDIA_SHARED if the media is present not mounted, and shared via USB mass storage.
Constant Value: "shared"
You need to go to your USB Mass Storage options and turn off USB storage.
Upvotes: 2
Reputation: 133570
I have a samsung galaxy s3 (running android 4.1.2) and my internal memory is named sdCard0 and My external sd card named as extSdCard.
So Environment.getExternalStorageDirectory() returned the path of sdCard0 which my internal phone memory
In such cases you can use the following to get the actual path.
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 actual path you can write files to sdcard.
Upvotes: 0
Reputation: 5795
here is the deal, you are using
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/GPStracker/data/");
instead use -
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdcard + "/GPStracker/data");
here we didn't use second '/' because mkdirs()
misinterpret it as creating recursive directories.
you will not get this exception. And check if you pass your filename with a '/' appended before or it works this way as well.
Upvotes: 0