欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

恢复出厂设置和格式化SD卡

程序员文章站 2022-05-25 23:36:42
...

最近收到一份需求:恢复出厂设置和格式化Sdcard,提供接口供第三方应用调用;
将接口添加进系统应用Settings中,通过ContentProvider call实现夸进程调用,调用代码简洁

 package com.android.settings;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.ServiceManager;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.android.settings.deviceinfo.StorageSettings.UnmountTask;
import com.android.settings.deviceinfo.StorageWizardFormatProgress;
import com.android.settings.deviceinfo.StorageWizardFormatConfirm;


public class SettingsSdkContentProvider extends ContentProvider {
    public static final String TAG = "SettingsSdkContentProvider";
    private static final String SYNC_DEV_TIME_METHOD = "syncDevTime";
    public static final String FORMAT_SDCARD_METHOD = "formatSdcard";
    public static final String FACTORY_RESET_METHOD = "factoryReset";

    private Context context;
    
    public SettingsSdkContentProvider() {
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // Implement this to handle requests to delete one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public String getType(Uri uri) {
        // TODO: Implement this to handle requests for the MIME type of the data
        // at the given URI.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO: Implement this to handle requests to insert a new row.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public boolean onCreate() {
        // TODO: Implement this to initialize your content provider on startup.
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        // TODO: Implement this to handle query requests from clients.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        // TODO: Implement this to handle requests to update one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Nullable
    @Override
    public Bundle call(@NonNull String method, @Nullable String arg, @Nullable Bundle extras) {
        Log.d(TAG, "method : " + method + " - arg : " + arg);
        Bundle backBundle = new Bundle();
        context = getContext();
        if (null == method) {
            return null;
        }
        if (method.equals(SYNC_DEV_TIME_METHOD)) {
            SystemClock.setCurrentTimeMillis(Long.parseLong(arg));
        } else if (method.equals(FORMAT_SDCARD_METHOD)) {
            formatSdcard(context);
        } else if (method.equals(FACTORY_RESET_METHOD)) {
            factoryReset(context);
        } else {
            Log.e(TAG, "unknow method !!! ");
        }

        return backBundle;
    }
    private void formatSdcard(Context context) {
        Log.d(TAG, "[formatSdcard] start --> ");
        StorageManager sm = context.getSystemService(StorageManager.class);
        final List<VolumeInfo> volumes = sm.getVolumes();
        for (VolumeInfo vol : volumes) {
            DiskInfo diskInfo = vol.getDisk();
            if (diskInfo != null && diskInfo.isSd()) {
                Log.d(TAG, "SD disk id : " + diskInfo.getId());
                //new UnmountTask(context, vol).execute();
                /*final Intent intent = new Intent(context, StorageWizardFormatProgress.class);
                intent.putExtra(DiskInfo.EXTRA_DISK_ID, diskInfo.getId());
                intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
                intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORGET_UUID, vol.getFsUuid());
                context.startActivity(intent);*/
                new PartitionTask().execute(diskInfo.getId());
            }
        }
    }

    private void factoryReset (Context context) {
        Log.d(TAG, "[factoryReset] start --> ");
        Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
        intent.setPackage("android");
        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
        context.sendBroadcast(intent);
    }

    class PartitionTask extends AsyncTask<String, Integer, Exception> {

        @Override
        protected Exception doInBackground(String... params) {
            StorageManager sm = context.getSystemService(StorageManager.class);
            try {
                sm.partitionPublic(params[0]);
                return null;
            } catch (Exception e) {
                Log.e(TAG, "[formatSdcard] e : " + e);
                return e;
            }
        }

        @Override
        protected void onPostExecute(Exception e) {
            super.onPostExecute(e);
            boolean isResult = true;
            if (e != null) {
                //format sdcard fail
                isResult = false;
            }
            Log.d(TAG, "PartitionTask [onPostExecute] isResult : " + isResult);
        }
    }
}

ContentProvider添加进Manifest文件中

    <!-- provider for third APP -->
    <provider
        android:name=".SettingsSdkContentProvider"
        android:authorities="com.android.setting.SettingsSdkContentProvider"
        android:enabled="true"
        android:exported="true">
    </provider>

第三方应用调用方式

   public static final Uri SETTINGS_sdk_URI = Uri.parse("content://com.android.setting.SettingsSdkContentProvider");
    public static final String FACTORY_RESET_METHOD = "factoryReset";
    
    public static void factoryReset(Context context) {
        context.getContentResolver().call(SETTINGS_sdk_URI,
                FACTORY_RESET_METHOD, null, null);
    }