简体   繁体   English

Android没有保存到SD卡

[英]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. 我想将文本文件保存到我插入运行棒棒糖的HTC One M8的SD卡中。 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 然后我尝试手动输入我的SD卡的位置,看看是否会工作,但它最终抛出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 示例: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". 主外部存储:在内置的共享存储中,“用户可以通过插入USB电缆并将其作为驱动器安装在主机上”进行访问。 Example: When we say Nexus 5 32 GB. 示例:当我们说Nexus 5 32 GB时。

Secondary External Storage: Removable storage. 辅助外部存储:可移动存储。 Example: SD Card. 示例:SD卡。

getExternalStorageDirectory ()

It will return path of the primary external storage directory 它将返回主外部存储目录的路径

To access removable SD (Secondary external storage) there are below APIs: 要访问可移动SD(辅助外部存储),有以下API:

getExternalFilesDirs(), getExternalCacheDirs(), and getExternalMediaDirs() getExternalFilesDirs(), getExternalCacheDirs(),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. 如果Android设备在此处指导处理多个外部存储时,我们可以使用以下代码来检测Android kitkat或更高版本的数据写入位置。

    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 我想将文本文件保存到我插入运行棒棒糖的HTC One M8的SD卡中

You are welcome to try getExternalFilesDirs() , getExternalCacheDirs() , and getExternalMediaDirs() on Context . 欢迎您在Context上尝试getExternalFilesDirs()getExternalCacheDirs()getExternalMediaDirs() 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 ). 对于这些方法,如果它们返回多个条目,则第二个和后续条目应位于可移动介质上,指向可以读取和写入的目录,而无需任何特定权限(例如, WRITE_EXTERNAL_STORAGE )。

Outside of those locations, for devices that shipped with Android 4.4+, you have no access to removable storage . 在这些位置之外,对于Android 4.4+附带的设备, 您无法访问可移动存储

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. 我认为这是因为HTC one修改了sdcard挂载点,你应该尝试使用adb shell ls -l命令找出sdcard挂载的路径。

For example in nexus 4: 例如在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 你应该确保它不是一个链接: 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. 路径/mnt/shell/emulated/0实际上是sdcard路径。

Try read How can I get external SD card path for Android 4.0+? 尝试阅读如何获取Android 4.0+的外部SD卡路径? too, this may help you a lot. 这也许可以帮到你很多。

UPDATE 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. 因此,您最好尝试/storage/emulated/*目录,以找出哪个是您的SD卡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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