Android 写入不同SD卡时出错

Android 写入不同SD卡时出错,android,sd-card,fileoutputstream,Android,Sd Card,Fileoutputstream,我正在编写一种方法,将文件写入设备上的任何sd卡 例如,我得到了三星Galaxy S4的两个sd卡路径:/storage/emulated/0是内部sd卡的路径,它等于Environment.getExternalStorageDirectory()和/storage/extSdCard 以下是获取可用SD卡根路径列表的方法: public static String[] getStorageDirectories() { // Final set of paths final

我正在编写一种方法,将文件写入设备上的任何sd卡

例如,我得到了三星Galaxy S4的两个sd卡路径:/storage/emulated/0是内部sd卡的路径,它等于
Environment.getExternalStorageDirectory()
和/storage/extSdCard

以下是获取可用SD卡根路径列表的方法:

public static String[] getStorageDirectories()
{
    // Final set of paths
    final Set<String> rv = new HashSet<String>();
    // Primary physical SD-CARD (not emulated)
    final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
    // All Secondary SD-CARDs (all exclude primary) separated by ":"
    final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
    // Primary emulated SD-CARD
    final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
    if(TextUtils.isEmpty(rawEmulatedStorageTarget))
    {
        // Device has physical external storage; use plain paths.
        if(TextUtils.isEmpty(rawExternalStorage))
        {
            // EXTERNAL_STORAGE undefined; falling back to default.
            rv.add("/storage/sdcard0");
        }
        else
        {
            rv.add(rawExternalStorage);
        }
    }
    else
    {
        // Device has emulated storage; external storage paths should have
        // userId burned into them.
        final String rawUserId;
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
        {
            rawUserId = "";
        }
        else
        {
            final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
            final String[] folders = DIR_SEPORATOR.split(path);
            final String lastFolder = folders[folders.length - 1];
            boolean isDigit = false;
            try
            {
                Integer.valueOf(lastFolder);
                isDigit = true;
            }
            catch(NumberFormatException ignored)
            {
            }
            rawUserId = isDigit ? lastFolder : "";
        }
        // /storage/emulated/0[1,2,...]
        if(TextUtils.isEmpty(rawUserId))
        {
            rv.add(rawEmulatedStorageTarget);
        }
        else
        {
            rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
        }
    }
    // Add all secondary storages
    if(!TextUtils.isEmpty(rawSecondaryStoragesStr))
    {
        // All Secondary SD-CARDs splited into array
        final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
        Collections.addAll(rv, rawSecondaryStorages);
    }

    return rv.toArray(new String[rv.size()]);
}
现在,当我将文件写入第一个目录/storage/emulated/0时,该文件创建得很好。 但是第二个dir-/storage/extSdCard返回了一个错误。 这是我的stacktrace和日志,带有检查路径(这是第一行):

怎么了?我怎样才能修好它

怎么了

您似乎认为
Environment.getExternalStorageDirectory()
与SD卡有关。该方法返回的根不是(从SDK的角度来看也不是)

但是,更重要的是,这些未记录和不受支持的脚本意味着,用于访问可移动存储(比如您正在尝试的)的各种人的脚本在Android 4.4中不再有效

我需要接触设备上的所有SD卡


从Android 4.4开始,这已经不可能了,而且在任何版本的Android上都不受支持。

您知道这个环境。getExternalStorageDirectory().getAbsolutePath()?我指定需要访问设备上的所有SD卡。我已经给出了一个方法来达到他们所有人。Environment.getExternalStorageDirectory().getAbsolutePath()只返回设备上的第一张SD卡,我是否注定要写入外部存储,不管它可能低至2GB,ExtSD卡或任何可移动SD卡(目前常见的情况)可能为32GB,而我无法使用它?@user2976267:欢迎您使用Android 4.4的
getExternalFilesDirs()
在可移动存储器上获得一个可读写位置的方法。你不能在Android 4.4上处理可移动存储上的任意位置。哦,太好了,所以我可以使用我在4.4之前的问题中描述的方法,以及4.4及以上版本的getExternalFilesDirs()方法-是吗?@user2976267:“我可以使用我在4.4之前的问题中描述的方法”-我不会。
public static boolean writeExternal(InputStream source, String filePath) {
    Log.d("MyLog", "dest="+filePath);
// собственно запись на флешку

File dest = new File(filePath);
FileOutputStream writer = null;
try {
if (!dest.exists()) {
    Log.d("MyLog","creates");
dest.getParentFile().mkdirs();
dest.createNewFile();
}

writer = new FileOutputStream(dest);
writeFromInputToOutput(source, writer);
Log.d("MyLog","writes a file "+filePath);
return true;
}
catch (IOException e) {
e.printStackTrace();
Log.d("MyLog","Error");
return false;
}
finally {
    Log.d("MyLog","file written");
close(writer);
}
}
09-15 01:32:24.124: D/MyLog(26216): dest=/storage/extSdCard/Molitvoslovaudio/morning.mp3
09-15 01:32:24.124: D/MyLog(26216): creates
09-15 01:32:24.124: W/System.err(26216): java.io.IOException: open failed: ENOENT (No such file or directory)
09-15 01:32:24.139: W/System.err(26216):    at java.io.File.createNewFile(File.java:946)
09-15 01:32:24.139: W/System.err(26216):    at ru.eyescream.prayer.FileMgr.writeExternal(FileMgr.java:156)
09-15 01:32:24.139: W/System.err(26216):    at ru.eyescream.prayer.Downloader$Downloading.onPostExecute(Downloader.java:183)
09-15 01:32:24.139: W/System.err(26216):    at ru.eyescream.prayer.Downloader$Downloading.onPostExecute(Downloader.java:1)
09-15 01:32:24.139: W/System.err(26216):    at android.os.AsyncTask.finish(AsyncTask.java:632)
09-15 01:32:24.139: W/System.err(26216):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
09-15 01:32:24.139: W/System.err(26216):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
09-15 01:32:24.139: W/System.err(26216):    at android.os.Handler.dispatchMessage(Handler.java:102)
09-15 01:32:24.139: W/System.err(26216):    at android.os.Looper.loop(Looper.java:157)
09-15 01:32:24.139: W/System.err(26216):    at android.app.ActivityThread.main(ActivityThread.java:5356)
09-15 01:32:24.139: W/System.err(26216):    at java.lang.reflect.Method.invokeNative(Native Method)
09-15 01:32:24.139: W/System.err(26216):    at java.lang.reflect.Method.invoke(Method.java:515)
09-15 01:32:24.139: W/System.err(26216):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
09-15 01:32:24.139: W/System.err(26216):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
09-15 01:32:24.139: W/System.err(26216):    at dalvik.system.NativeStart.main(Native Method)
09-15 01:32:24.139: W/System.err(26216): Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
09-15 01:32:24.139: W/System.err(26216):    at libcore.io.Posix.open(Native Method)
09-15 01:32:24.139: W/System.err(26216):    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
09-15 01:32:24.139: W/System.err(26216):    at java.io.File.createNewFile(File.java:939)
09-15 01:32:24.139: W/System.err(26216):    ... 14 more
09-15 01:32:24.139: D/MyLog(26216): Error