MasterGberry
MasterGberry

Reputation: 2860

Cannot write to SD Card on Android phone

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

Answers (3)

DigCamara
DigCamara

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

Raghunandan
Raghunandan

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

Darpan
Darpan

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

Related Questions