Setting中格式化SD卡
来源:互联网 发布:网络运行维护培训课程 编辑:程序博客网 时间:2024/05/01 12:29
今天分析setting中直接格式化的流程,直接上代码:
Setting中的MediaFormat.java中的mFinalClickListener 这个回调,就是调用Format的地方:其是其了一个Service。
private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() { public void onClick(View v) { if (Utils.isMonkeyRunning()) { return; } Intent intent = new Intent(ExternalStorageFormatter.FORMAT_ONLY); intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME); // Transfer the storage volume to the new intent final StorageVolume storageVolume = getIntent().getParcelableExtra( StorageVolume.EXTRA_STORAGE_VOLUME); intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, storageVolume); startService(intent); finish(); } };
ExternalStorageFormatter.java就是这个Service,Service刚建立调用onCreate函数,起来在MountService中注册了回调,然后持一个睡眠锁。
StorageEventListener mStorageListener = new StorageEventListener() {//放在MountService中的回调 @Override public void onStorageStateChanged(String path, String oldState, String newState) { Log.i(TAG, "Received storage state changed notification that " + path + " changed state from " + oldState + " to " + newState); updateProgressState();//updateProgressState(主要的函数) } }; @Override public void onCreate() { super.onCreate(); if (mStorageManager == null) { mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE); mStorageManager.registerListener(mStorageListener); } mWakeLock = ((PowerManager)getSystemService(Context.POWER_SERVICE)) .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ExternalStorageFormatter"); mWakeLock.acquire(); }
调用了onCreate之后,会调用onStartCommand函数
@Override public int onStartCommand(Intent intent, int flags, int startId) { if (FORMAT_AND_FACTORY_RESET.equals(intent.getAction())) { mFactoryReset = true; } if (intent.getBooleanExtra(EXTRA_ALWAYS_RESET, false)) { mAlwaysReset = true; } mReason = intent.getStringExtra(Intent.EXTRA_REASON); mStorageVolume = intent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);//获取StorageVolume if (mProgressDialog == null) {//第一次调用的时候,新建一个Dialog mProgressDialog = new ProgressDialog(this); mProgressDialog.setIndeterminate(true); mProgressDialog.setCancelable(true); mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); if (!mAlwaysReset) { mProgressDialog.setOnCancelListener(this); } updateProgressState();//第一次调用updateProgressState mProgressDialog.show(); } return Service.START_REDELIVER_INTENT; }
下面我们就来分析下主要的函数,第一次会将其卸载,然后MountService会将其Volume的状态改变,并且通知回调函数来调用updateProgressState函数。第二次过来已经是unmounted了,这时候将其格式化,最后再挂载sd卡。
void updateProgressState() { String status = mStorageVolume == null ? Environment.getExternalStorageState() : mStorageManager.getVolumeState(mStorageVolume.getPath()); if (Environment.MEDIA_MOUNTED.equals(status)//第一次调用的时候,发现Volume是mounted,就将它卸载 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)) { updateProgressDialog(R.string.progress_unmounting); IMountService mountService = getMountService(); final String extStoragePath = mStorageVolume == null ? Environment.getLegacyExternalStorageDirectory().toString() : mStorageVolume.getPath(); try { // Remove encryption mapping if this is an unmount for a factory reset. mountService.unmountVolume(extStoragePath, true, mFactoryReset); } catch (RemoteException e) { Log.w(TAG, "Failed talking with mount service", e); } } else if (Environment.MEDIA_NOFS.equals(status) || Environment.MEDIA_UNMOUNTED.equals(status) || Environment.MEDIA_UNMOUNTABLE.equals(status)) {//当第二次回调过来,应该是已经卸载了,这时候再去格式化;由于format耗时其了一个thread updateProgressDialog(R.string.progress_erasing); final IMountService mountService = getMountService(); final String extStoragePath = mStorageVolume == null ? Environment.getLegacyExternalStorageDirectory().toString() : mStorageVolume.getPath(); if (mountService != null) { new Thread() { @Override public void run() { boolean success = false; try { mountService.formatVolume(extStoragePath); success = true; } catch (Exception e) { Toast.makeText(ExternalStorageFormatter.this, R.string.format_error, Toast.LENGTH_LONG).show(); } if (success) { if (mFactoryReset) { Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_REASON, mReason); sendBroadcast(intent); // Intent handling is asynchronous -- assume it will happen soon. stopSelf(); return; } } // If we didn't succeed, or aren't doing a full factory // reset, then it is time to remount the storage. if (!success && mAlwaysReset) { Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_REASON, mReason); sendBroadcast(intent); } else {//格式化完后再挂载SD卡 try { mountService.mountVolume(extStoragePath); } catch (RemoteException e) { Log.w(TAG, "Failed talking with mount service", e); } } stopSelf();//最后将Service暂停了 return; } }.start(); } else { Log.w(TAG, "Unable to locate IMountService"); } } else if (Environment.MEDIA_BAD_REMOVAL.equals(status)) { fail(R.string.media_bad_removal); } else if (Environment.MEDIA_CHECKING.equals(status)) { fail(R.string.media_checking); } else if (Environment.MEDIA_REMOVED.equals(status)) { fail(R.string.media_removed); } else if (Environment.MEDIA_SHARED.equals(status)) { fail(R.string.media_shared); } else {//如果发过来的状态不对,直接停止Service fail(R.string.media_unknown_state); Log.w(TAG, "Unknown storage state: " + status); stopSelf(); } }调完Format,紧接着就调mount,会不会有问题。因为这几个函数都是阻塞的,一定要等vold执行完,才结束,所以连续调也不会有问题,但是一定要起线程。
1 0
- Setting中格式化SD卡
- Setting卸载SD卡,可以格式化,卸载过程中还可以卸载问题
- Setting卸载SD卡,可以格式化,卸载过程中还可以卸载问题
- linux 格式化SD卡
- android 格式化SD卡
- linux sd卡格式化
- SD卡彻底格式化
- 分析setting源代码获取sd卡大小
- 格式化SD卡/卸载SD卡
- pc上格式化sd卡
- linux 下格式化 SD卡
- Ubuntu下格式化SD卡
- linux 下格式化 SD卡
- ubuntu下格式化sd卡
- ubuntu下格式化sd卡
- linux下格式化SD卡
- linux 下格式化SD卡
- 运用反射格式化SD卡
- 将GPIUmage集成到项目中
- Integray Image(积分图)
- [cocos2dx]事件分发机制--lua源码(二)
- html 横线的代码
- 咕噜小金鱼前来报到
- Setting中格式化SD卡
- ajax 小结
- leetcode 52: Maximum Subarray
- JForum 的 SSO集成
- hdu 5316 Magician 线段树
- MFC-导入显示bmp图片
- <Web> jsp:EL表达式+C标签
- Android编程权威指南-第5章:挑战练习
- 判断未来是星期几