這今天項目中有一個將設備的數據文件複製到U盤的功能,複製完成之後,在設備看U盤的文件都是好的,數據也正常,當拔出U盤後放到電腦上,有時就會出現文件爲0B的情況,後來才發現,是U盤沒有安全卸載的原因。
初期的設想是控制程序跳轉到android的設置的存儲界面,讓用戶進行點擊U盤的安全卸載選項,代碼如下:
Intent intent = new Intent(Settings.ACTION_MEMORY_CARD_SETTINGS);
startActivity(intent);
很簡單粗暴,直接跳轉界面。
But,問題來了,系統的界面和當前設備的UI風格不統一。這就是個很讓人撓頭的問題了,只能自己實現U盤卸載的功能了。
網上查了好多的資料,感覺沒有自己想要的功能,無奈之下,給硬件組要了一份當前系統的Setting的源碼,請教了一圈,最後確定了存儲功能的源碼位置:
在這個文件夾下的Memory.java這個文件中,下面來看看U盤卸載功能是如何實現的,直接上源碼:
private void doUnmount() {
// Present a toast here
Toast.makeText(getActivity(), unmoutUSBorSD.equals("usb")?R.string.custom_usb_unmount_inform_text:R.string.custom_sd_unmount_inform_text, Toast.LENGTH_SHORT).show();
IMountService mountService = getMountService();
try {
sLastClickedMountToggle.setEnabled(false);
sLastClickedMountToggle.setTitle(getString(R.string.sd_ejecting_title));
sLastClickedMountToggle.setSummary(getString(R.string.sd_ejecting_summary));
mountService.unmountVolume(sClickedMountPoint, true, false);
} catch (RemoteException e) {
// Informative dialog to user that unmount failed.
showDialogInner(DLG_ERROR_UNMOUNT);
}
}
關鍵點就兩句 IMountService mountService = getMountService();和mountService.unmountVolume(sClickedMountPoint, true, false); ,其餘的和U盤卸載基本沒有關係,下面來看 getMountService()方法:
private synchronized IMountService getMountService() {
if (mMountService == null) {
IBinder service = ServiceManager.getService("mount");
if (service != null) {
mMountService = IMountService.Stub.asInterface(service);
} else {
Log.e(TAG, "Can't get mount service");
}
}
return mMountService;
}
只是獲取了系統的一個服務,那麼unmountVolume(sClickedMountPoint, true, false);中的sClickedMountPoint又是啥呢?
接着找,如下:
final StorageVolume volume = category.getStorageVolume();
if (volume != null && category.mountToggleClicked(preference)) {
sLastClickedMountToggle = preference;
sClickedMountPoint = volume.getPath();
String state = mStorageManager.getVolumeState(volume.getPath());
if (volume.getPath().contains("usb")){
unmoutUSBorSD = "usb";
}else{
unmoutUSBorSD = "sd";
}
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
unmount();
} else {
mount();
}
return true;
}
可以確定是U盤的掛載路徑,OK到這裏,基本U盤的卸載方法已經明瞭,如果使用系統的服務或方法的話,採用反射機制是一個不錯的方式,過程不在進行說明,增加如下文件
文件下載地址: https://download.csdn.net/download/u011685953/10992318
使用方法如下:
//安全卸載U盤
public void doUnMountU() {
IMountService service = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
try {
service.unmountVolume(App_DataPara.getApp().GetExternalStorageDirectory(), true, false);
} catch (RemoteException e) {
e.printStackTrace();
}
}
App_DataPara.getApp().GetExternalStorageDirectory()爲需要卸載的U盤的掛載的文件目錄。String類型
因爲踩過坑,所以記錄一下,同時分享出來,哪怕對一個人有幫助也行!