android通過反射獲取內建外接儲存器列表
android系統自從升級到2.3以後,多一個功能,可以判斷儲存卡是否是可以解除安裝的。Environment.isExternalStorageRemovable(),通過此方法我們可以知道手機上的儲存卡是手機自帶的還是外邊可插拔的SD卡,當然此種情況是指只有一個卡的情況。
但是現在國內的大多數手機都支援雙儲存卡:
1、即手機內建的有2G、4G或8G的內部儲存卡,預設安裝的應用與資料都會到這個卡中,使用者不買可插拔的SD卡,也可使用。
2、手機的儲存空間畢竟有限,所以手機也支援外接的SD卡,或者叫TF卡、擴充套件卡等。
那麼這時候問題就來了,在程式中我們如何可以判斷哪個路徑對應的是內建儲存卡,哪個對應的是外接儲存卡。有人說用Environment.getExternalStorageDirectory()方法得到不就是SD卡嗎,這種方法明顯不適用的,尤其在4.0以後。
恰恰相反,使用上面的方法得到的大多數是手機內部對應的SD卡(/mnt/sdcard 4.1系統以下,4.1直接變為/storage/sdcard0),下面我總結了一些較常見的外部SD卡的路徑:
/mnt/sdcard2 /mnt/sdcard-ext /mnt/ext_sdcard /mnt/sdcard/SD_CARD
/mnt/sdcard/extra_sd /mnt/extrasd_bind /mnt/sdcard/ext_sd
/mnt/sdcard/external_SD/storage/sdcard1 /storage/extSdCard
如何直接取,而不是hardcode來定死呢,用這個方法getVolumePaths,通過反射機制得到路徑,然後判斷即可。
我們知道android上一般都有外接的儲存卡,
但是通過Environment.getExternalStorageDirectory()獲取的是內建的儲存卡位置
(也有的手機可以在系統中修改預設儲存)
那麼如何獲取外接儲存卡的位置呢?
後發現可以通過反射來獲取
StorageManager中有幾個共有的方法被標識為@hide,可能出於安全考慮?
比如,getVolumePaths,getVolumeList所以用不了,
而反射可以做到,
具體程式碼如下
-
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
- try {
- Class<?>[] paramClasses = {};
- Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", paramClasses);
- getVolumePathsMethod.setAccessible(true);
- Object[] params = {};
- Object invoke = getVolumePathsMethod.invoke(storageManager, params);
- for (int i = 0; i < ((String[])invoke).length; i++) {
- System.out.println(((String[])invoke)[i]);
- }
- } catch (NoSuchMethodException e1) {
- e1.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
還有點問題就是無法區分內建卡和外接卡