为什么getExternalFilesDirs()在某些设备上不起作用?

时间:2015-10-26 16:00:23

标签: android android-sdcard android-external-storage

我的应用在Android 5.0上运行。我使用方法getExternalFilesDirs()来检查外部SD卡是否可用。如果返回的值超过1 File,则表示存在外部SD卡。

但是在某些设备上(例如Elephone G2),方法getExternalFilesDirs()只返回一个主存储目录。我确定该设备有外置SD卡(/ storage / sdcard1 /)。

任何人都可以给我答案吗?

3 个答案:

答案 0 :(得分:12)

要使getExternalFilesDirs返回sdcard的路径,OEM必须在设备特定的init.rc文件中设置SECONDARY_STORAGE环境变量,如下所述: https://source.android.com/devices/storage/config-example.html

在这里查看getExternalFilesDirs的来源: http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/app/ContextImpl.java#1039

该值来自Environment.buildExternalStorageAppFilesDirs。看看这个来源: http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/os/Environment.java#206

该值取决于mExternalDirsForApp,而adb shell又通过读取SECONDARY_STORAGE变量的内容来填充: http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/os/Environment.java#136

如您所见,如果未设置SECONDARY_STORAGE变量,则不会返回SD卡路径。 您可以转到echo $SECONDARY_STORAGE并查看update [RegistryCopy].[dbo].[RegFile_New] SET r.[FileNo] = v.[Cont#Account (New ACC)] where r.[FileNo] IN ( SELECT r.[FileNo] FROM [RegistryCopy].[dbo].[RegFile_New] as R INNER JOIN [Registry_Malta_Recovered].[dbo].OLD_NEW_AccountsFromSap as v ON r.FileNo] = v.[Acct in legacy (Old ACC)] where r.[FileNo] = ('1000040000') )

的输出来进行交叉检查

答案 1 :(得分:6)

在我使用此代码的项目中我没有任何问题。

getExternalFilesDirs方法返回2个长度的数组。

Dirs[0] ==> Internal Sorage Dirs[1] ==> External Storage

 File[] Dirs = ContextCompat.getExternalFilesDirs(MyApp.GetContext(), null);

答案 2 :(得分:0)

这个问题也存在于某些联想设备中。

我的解决方案就是这个。

String EXTERNAL_SD_PATH1;
String EXTERNAL_SD_PATH2;

public boolean hasExternalSDCard()
{
    try
    {
        String state = Environment.getExternalStorageState();
        if(Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state))
        return true;
    }
    catch (Throwable e)
    {}

    return false;
}

        @SuppressLint("SdCardPath")
        protected synchronized void _prepareStorage()
        {
            EXTERNAL_SD_PATH1 = null;
            EXTERNAL_SD_PATH2 = null;
            if (hasExternalSDCard())
            {
                try
                {
                    if(VERSION_SDK_INT > 18)
                    {
                        Context context = getContext();
                        File[]  sds = getExternalFilesDirs("");

                        if(sds == null)
                            return;

                        if(sds.length >= 2)
                        {
                            EXTERNAL_SD_PATH1 = TextWorker.getSubStringBeforeLastMark(sds[1].getAbsolutePath(),"/Android/");
                            if(sds.length > 2)
                                EXTERNAL_SD_PATH2 = TextWorker.getSubStringBeforeLastMark(sds[2].getAbsolutePath(),"/Android/");
                        }
                        else
                        {
                            String internal = sds[0].getAbsolutePath();
                            internal = TextWorker.getSubStringBeforeLastMark(internal,"/Android/");
                            int len = internal.length();
                            int num = Integer.valueOf(internal.substring(len - 1));

                            String ex1 = internal.substring(0, len-1) + (num+1);
                            File sd1 = new File(ex1);
                            if(sd1.exists())
                                EXTERNAL_SD_PATH1 = sd1.getAbsolutePath();

                            String ex2 = internal.substring(0, len-1) + (num+2);
                            File sd2 = new File(ex2);
                            if(sd2.exists())
                                EXTERNAL_SD_PATH2 = sd2.getAbsolutePath();
                        }
                    }

                    else
                    {
                        File sd = Environment.getExternalStorageDirectory();
                        String path = sd.getAbsolutePath();
                        if (sd.exists() && (path.contains("/mnt/") || path.contains("/storage") || path.contains("/sdcard")) && (!path.contains("emulate")))
                        {
                            EXTERNAL_SD_PATH1 = path;
                        }
                    }
                }
                catch (Throwable e)
                {}
            }

        }


        public static String getSubStringBeforeLastMark(String str,String mark)
    { 
        int l = str.lastIndexOf(mark);
        if(l == -1 || l == 0)
            return "";

        return str.substring(0, l);
    }