【问题标题】:Android getExternalFilesDirs method is not returning SD Card on EmulatorAndroid getExternalFilesDirs 方法未在模拟器上返回 SD 卡
【发布时间】:2018-07-19 11:27:20
【问题描述】:

我需要确定 SD 卡是否可用。我目前正在使用 getExternalFilesDirs 方法,然后使用 Environment.isExternalStorageRemovable 来验证路径是否是可移动 SD 卡。这在操作系统大于 Lollipop 的实际设备上运行良好,但是当我尝试使用模拟 SD 卡设置模拟器时,我可以在模拟器上看到 SD 卡,但 getExternalFilesDirs 方法无法返回 SD 卡存储路径,因此我只看到本地存储。

我需要在模拟器中的某个地方进行设置吗? 我应该只信任实体电话而不是模拟器吗?

【问题讨论】:

    标签: android android-emulator android-sdcard


    【解决方案1】:

    尝试使用此代码:

    import android.content.Context;
    import android.os.Build;
    import android.os.IBinder;
    
    import java.io.File;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.List;
    
    public class RemovableStorageFinder {
    
        public static File getRemovabeStorageDir(Context context) {
            try {
                List<File> storages = getRemovabeStorages(context);
                if (!storages.isEmpty()) {
                    return storages.get(0);
                }
            } catch (Exception ignored) {
            }
            final String SECONDARY_STORAGE = System.getenv("SECONDARY_STORAGE");
            if (SECONDARY_STORAGE != null) {
                return new File(SECONDARY_STORAGE.split(":")[0]);
            }
            return null;
        }
    
        public static List<File> getRemovabeStorages(Context context) throws Exception {
            List<File> storages = new ArrayList<>();
    
            Method getService = Class.forName("android.os.ServiceManager")
                    .getDeclaredMethod("getService", String.class);
            if (!getService.isAccessible()) getService.setAccessible(true);
            IBinder service = (IBinder) getService.invoke(null, "mount");
    
            Method asInterface = Class.forName("android.os.storage.IMountService$Stub")
                    .getDeclaredMethod("asInterface", IBinder.class);
            if (!asInterface.isAccessible()) asInterface.setAccessible(true);
            Object mountService = asInterface.invoke(null, service);
    
            Object[] storageVolumes;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                String packageName = context.getPackageName();
                int uid = context.getPackageManager().getPackageInfo(packageName, 0).applicationInfo.uid;
                Method getVolumeList = mountService.getClass().getDeclaredMethod(
                        "getVolumeList", int.class, String.class, int.class);
                if (!getVolumeList.isAccessible()) getVolumeList.setAccessible(true);
                storageVolumes = (Object[]) getVolumeList.invoke(mountService, uid, packageName, 0);
            } else {
    
                Method getVolumeList = mountService.getClass().getDeclaredMethod("getVolumeList");
                if (!getVolumeList.isAccessible()) getVolumeList.setAccessible(true);
                storageVolumes = (Object[]) getVolumeList.invoke(mountService, (Object[]) null);
            }
    
            for (Object storageVolume : storageVolumes) {
                Class<?> cls = storageVolume.getClass();
                Method isRemovable = cls.getDeclaredMethod("isRemovable");
                if (!isRemovable.isAccessible()) isRemovable.setAccessible(true);
                if ((boolean) isRemovable.invoke(storageVolume, (Object[]) null)) {
                    Method getState = cls.getDeclaredMethod("getState");
                    if (!getState.isAccessible()) getState.setAccessible(true);
                    String state = (String) getState.invoke(storageVolume, (Object[]) null);
                    if (state.equals("mounted")) {
                        Method getPath = cls.getDeclaredMethod("getPath");
                        if (!getPath.isAccessible()) getPath.setAccessible(true);
                        String path = (String) getPath.invoke(storageVolume, (Object[]) null);
                        storages.add(new File(path));
                    }
                }
            }
    
            return storages;
        }
    
    }
    

    要检查 SD 是否存在,请使用您活动中的以下代码行:

                RemovableStorageFinder removableStorageFinder = new RemovableStorageFinder();
    
                File thisFile = removableStorageFinder.getRemovabeStorageDir(this);
    
    
                if(thisFile != null){
    
                 //  There is an SD card, perform your logic here.
                }
    

    PS:我不确定这是否能解决您面临的模拟器问题,但它通常是确定 SD 卡是否存在的更好方法。祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-23
      • 1970-01-01
      相关资源
      最近更新 更多