我需要确定SD卡是否可用。我目前正在通过使用getExternalFilesDirs方法然后通过Environment.isExternalStorageRemovable来验证路径是否为可移动SD卡。在操作系统大于Lollipop的实际设备上,这非常有用,但是当我尝试使用仿真的SD卡设置仿真器时,我可以在仿真器上看到SD卡,但是方法getExternalFilesDirs无法返回SD卡存储路径,结果我只能看到本地存储。
模拟器中需要设置的设置吗? 我应该只在模拟器上信任物理电话吗?
答案 0 :(得分:0)
尝试使用此代码代替
: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卡是否存在的更好方法。祝你好运!