简体   繁体   中英

Android not saving to SD card

I want to save a text file to the SD card I inserted into my HTC One M8 running lollipop. However when I run this code it saves to internal storage instead.

String FILENAME = "mysavefile.txt";

    File file = new File(Environment.getExternalStorageDirectory(), FILENAME);

    if (isExternalStorageWritable()) {
        errorSD.setVisibility(View.INVISIBLE);
        try {
            FileOutputStream fos = new FileOutputStream(file, false);
            fos.write(allInformation.getBytes(), 0, 81);
            fos.close();
            successfulSubmissionToast();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            errorSD.setVisibility(View.VISIBLE);
        } catch (IOException e) {
            e.printStackTrace();
        }

It should be saving to

/storage/ext_sd

but instead it is saving to

/storage/emulated/0

Then I tried manually entering in the location of my SD card to see if that would work but it ended up throwing the FileNotFoundException

File file = new File("/storage/ext_sd", FILENAME);

Edit: I believe the issue is that there are multiple external storages. One being permanent and one temporary. The question is how do you access the second one.

First of all, we need to understand about what is difference between Internal Storage, External Storage (aka primary external storage) and Secondary External Storage?

Internal Storage: is storage that is not accessible by the user, except via installed apps (or by rooting their device). Example: data/data/app_packageName

Primary External Storage: In built shared storage which is "accessible by the user by plugging in a USB cable and mounting it as a drive on a host computer". Example: When we say Nexus 5 32 GB.

Secondary External Storage: Removable storage. Example: SD Card.

getExternalStorageDirectory ()

It will return path of the primary external storage directory

To access removable SD (Secondary external storage) there are below APIs:

getExternalFilesDirs(), getExternalCacheDirs(), and getExternalMediaDirs()

Check there documentation for further information

If the Android device following the guide here when deal with multiple external storage, we can use the following code to detect where to write the data for Android kitkat or higher version.

    final String APP_EXTERNAL_CACHE = "Android" + File.separator + "data"
            + File.separator + getPackageName() + File.separator + "cache";
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        for (File file : getExternalCacheDirs()) {
            if (file != null) {
                String mountPoint = file.getAbsolutePath().replace(APP_EXTERNAL_CACHE, "");

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    if (Environment.isExternalStorageRemovable(file)) {
                        Log.d(TAG, "removable external " + file.getAbsolutePath());
                    }
                    if (Environment.isExternalStorageEmulated(file)) {
                        Log.d(TAG, "emulated internal " + file.getAbsolutePath());
                    }
                } else {
                    if (mountPoint.contains("emulated")) {
                        Log.d(TAG, "emulated internal " + mountPoint);
                    } else {
                        Log.d(TAG, "removable external " + mountPoint);
                    }
                }
            }
        }
    }

And declare the relating permission in the manifest.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

I want to save a text file to the SD card I inserted into my HTC One M8 running lollipop

You are welcome to try getExternalFilesDirs() , getExternalCacheDirs() , and getExternalMediaDirs() on Context . Note the plural form of the method name. For these methods, if they return more than one entry, the second and subsequent ones should be on removable media, pointing to directories that you can read and write, without any particular permission (eg, WRITE_EXTERNAL_STORAGE ).

Outside of those locations, for devices that shipped with Android 4.4+, you have no access to removable storage .

I think it's because HTC one modified the sdcard mount point, you should try adb shell ls -l commands to find out which path the sdcard mounted.

For example in nexus 4:

lrwxrwxrwx root     root              2015-03-24 18:26 sdcard -> /storage/emulated/legacy
drwxr-x--x root     sdcard_r          2015-03-24 18:26 storage

and you should make sure it is not a link: ls -l /storage/emulated/legacy

lrwxrwxrwx root     root              2015-03-24 18:26 legacy -> /mnt/shell/emulated/0

The path /mnt/shell/emulated/0 is actually sdcard path.

Try read How can I get external SD card path for Android 4.0+? too, this may help you a lot.

UPDATE

I tried this code:

    String test = "/storage/emulated/legacy"; // work
    //String test = "/mnt/shell/emulated/legacy"; // not work
    File sdDir = new File(test);
    if (sdDir.exists()) {
        File file = new File(test, "test.sdcard");
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

So you'd better try /storage/emulated/* directories to find out which is exactly your sdcard.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM