寫過這個功能的童鞋應該很理解我,當初找了大量的資料也只能做到在兩者都插入時分辨出哪個是哪個,只插入其中一方,則一臉無奈,當初我甚至在界面上寫"檢測U盤或SD卡插入,總容量爲xx,可用容量爲xx"這樣的,特別尬.
現在又要寫這個功能,而且是分成兩個模塊的,USB檢測就只檢測插入的U盤的容量(有三個U盤),SD卡檢測就只檢測插入的SD卡的容量.再用之前這種方法肯定是混不過去的了,沒辦法,一步步來解決吧.
首先要解決分辨USB和SD的問題,之所以難分辨是因爲Android自動掛載U盤和SD卡的路徑是相同的,都是在/storage/目錄下,而SD卡和U盤的掛載名稱五花八門,千奇百怪,如68EE-C662,9E20-8ACD,8624266024265389,我突然發現是可以根據名稱來的啊,看我列舉的這三個名稱,前兩個是U盤的,後面全數字的是SD卡,如果系統規則規定是這樣的話,那確實是可以的哈.
我找到的是另一種,不太懂的話通過Log看輸出,你就明白了,第二個參數建議"U"或"SD",分別表示U盤,SD卡
public static String getStoragePath(Context mContext,String keyword) {
String targetpath = "";
StorageManager mStorageManager = (StorageManager) mContext
.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
Method getUserLabel = storageVolumeClazz.getMethod("getUserLabel");
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String userLabel = (String) getUserLabel.invoke(storageVolumeElement);
String path = (String) getPath.invoke(storageVolumeElement);
//Log.d("zdd",userLabel);
if(userLabel.contains(keyword)){
targetpath = path;
}
//Log.d("zdd", "usb路徑為"+targetpath);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return targetpath ;
}
然後再來個簡單的判斷
String sdMntPath = tUtils.getStoragePath(SdCardTestActivity.this, "SD");
String sdContainer = getSDContainer(SdCardTestActivity.this, sdMntPath);
if (sdMntPath=="") {
text = "未檢測到外置SD卡";
}else {
text = "SD卡掛載路徑爲"+sdMntPath+"\n"
+"SD卡"+sdContainer;
}
主要是上面提到的那個靜態函數,注意static不能丟.
這樣就能分辨出SD卡和U盤了,但是經過我的測試只能得到一個U盤的插拔狀態,想多測幾個就直接崩潰,原因未知.
現在問題就變成了,該怎麼測試多個U盤的插拔狀態.
其實這個不難,因爲之前一直是被無法區分U盤和SD卡給難住的.
思路是:
遍歷/storage/目錄
得到一個String數組,第一個元素是emulated/0,這個不插U盤和SD卡也會存在的,
然後第二個元素如果插了SD卡,就是SD卡的名稱,如果沒插SD卡,就是U盤的名稱.
這麼說明白了吧,只要插了SD卡,它就在第二個元素的位置,不離不棄.
所以我們先通過上面提到的函數檢測是否插入了SD卡,沒插入的話,除了emulated/0之外的元素都是U盤,有幾個就表示插入了幾個U盤,插入了的話,不用我說,你也能明白吧.
String text = null;
boolean isSdExixt = tUtils.getStoragePath(UsbTestActivity.this, "SD")=="";
//myLog(String.valueOf(isSdExixt));
String[] list = getFunc();
//myLog(String.valueOf(list.length));
switch (list.length) {
case 1:
//SD卡和USB均未插入
text = "未檢測到U盤";
break;
case 2:
if (!isSdExixt) {
//只插入SD卡
text = "未檢測到U盤";
}else {
//插入一個U盤 路徑爲 list[1]
text = "U盤1號"+getUSBContainer(UsbTestActivity.this, list[1]);
}
break;
case 3:
if (!isSdExixt) {
//插入SD卡和一個U盤 路徑爲list[2]
text = "U盤1號"+getUSBContainer(UsbTestActivity.this, list[2]);
}else {
//插入兩個U盤 路徑分別爲list[1]和list[2]
text = "U盤1號"+getUSBContainer(UsbTestActivity.this, list[1])
+"\n"+"U盤2號"+getUSBContainer(UsbTestActivity.this, list[2]);
}
break;
case 4:
if (!isSdExixt) {
//插入SD卡和兩個U盤 路徑分別爲list[2]和list[3]
text = "U盤1號"+getUSBContainer(UsbTestActivity.this, list[2])
+"\n"+"U盤2號"+getUSBContainer(UsbTestActivity.this, list[3]);
}else {
//插入三個U盤 路徑分別爲list[1],list[2]和list[3]
text = "U盤1號"+getUSBContainer(UsbTestActivity.this, list[1])
+"\n"+"U盤2號"+getUSBContainer(UsbTestActivity.this, list[2])
+"\n"+"U盤3號"+getUSBContainer(UsbTestActivity.this, list[3]);
}
break;
case 5:
//插入SD卡和三個U盤 路徑分別爲list[2],list[3]和list[4]
text = "U盤1號"+getUSBContainer(UsbTestActivity.this, list[2])
+"\n"+"U盤2號"+getUSBContainer(UsbTestActivity.this, list[3])
+"\n"+"U盤3號"+getUSBContainer(UsbTestActivity.this, list[4]);
break;
default:
break;
}
txtShowUSBInfo.setText(text);
好了,就這些了.