最近在給一個應用裏面做一個內置的文件管理器,期間遇到一個問題,就是選擇不同手機的sd卡存儲和手機本身存儲。可以在兩者之間來回切換,經過一系列測試發現,現在的很多手機廠家定製的手機內存和sd卡內存的路徑都不同,用android系統自帶的api無法準確獲取區分sd卡和手機自身的準確路徑,比如再一臺手機上獲取的手機的路徑是/storage/emulated/0。很可能在另外一個手機上用同樣的方法獲取到的就不是這個路徑。
下面給出解決方案,大致思路是:首先獲取到手機(設備)中所有的存儲路徑,包括 手機自身的存儲路徑,sd卡存儲路徑,其他存儲路徑。返回的是一個存放路徑的String數組。然後我們對數組進行處理,一般第一位元素arr[0]就是手機自身的存儲路徑,arr[1]就是外置sd卡的存儲路徑。
獲取到路徑了,我們接下來就可以進行其他操作了。
下面是代碼
/**
* 得到所有的存儲路徑(內部存儲+外部存儲)
*
* @param context
* @return
*/
public static String[] getAllSdPaths(Context context) {
Method mMethodGetPaths = null;
String[] paths = null;
//通過調用類的實例mStorageManager的getClass()獲取StorageManager類對應的Class對象
//getMethod("getVolumePaths")返回StorageManager類對應的Class對象的getVolumePaths方法,這裏不帶參數
StorageManager mStorageManager = (StorageManager)context
.getSystemService(context.STORAGE_SERVICE);//storage
try {
mMethodGetPaths = mStorageManager.getClass().getMethod("getVolumePaths");
paths = (String[]) mMethodGetPaths.invoke(mStorageManager);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return paths;
}
接下來是在ManiActivity中進行調用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
strAllPath = FilesUtils.getAllSdPaths(this);
initView();// 控件初始化
setLayout();// 視圖切換
moblieStorgePath = strAllPath[0];// 手機
sDStorgePath = strAllPath[1];// sd卡
Log.e("moblieStorgePath", moblieStorgePath + "");
Log.e("strAllPath", strAllPath.length + "");
Log.e("strAllPath[0]", strAllPath[0]);
Log.e("strAllPath[1]", strAllPath[1]);
運行結果log:
經過與手機自帶文件管理器比對,strAllPath[0]爲手機自身的儲存,strAllPath[1]爲我的sd卡存儲。已經在oppo r9s ,紅米1s,小米2s上測試均可用。