Android系统SD卡升级

    一般在本地进行OTA升级时,将升级包拷贝到SD卡,然后进入recovery模式选择升级包进行升级,但不是很方便,于是做了一个小应用,通过调用RecoverySystem类中的接口来进行升级。实际上最终也是在recovery模式下进行升级,只不过是在应用层对升级包进行签名验证和发送升级命令。
    内容比较简单直接上代码。

一、主要类
SdCardUpgradeWarning.java
一个简单的Activity,对用户升级前进行一些警告提示。
SdCardUpgradeIntroduction.java
对升级过程一些注意事项的提示。
SdCardUpgradeProcess.java
这个是最主要的一个类,读取升级包并进行验证,然后调用installPackage进行升级。

二、详细代码

1.AndroidManifest.xml

<pre style="font-family: Consolas; font-size: 9.8pt; background-color: rgb(255, 255, 255);"><pre name="code" class="java"><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.windy.sdcardupgrade"
    android:sharedUserId="android.uid.system">

    <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
    <uses-permission android:name="android.permission.MASTER_CLEAR" />
    <uses-permission android:name="android.permission.REBOOT" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".SdCardUpgradeWarning"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SdCardUpgradeIntroduction"></activity>
        <activity
            android:name=".SdCardUpgradeProcess"
            android:configChanges="keyboardHidden|orientation"
            android:screenOrientation="portrait"></activity>
    </application>

</manifest>

 
 
   注意添加 
android:sharedUserId="android.uid.system",否则一些系统权限无法使用,如重启。 

2.SdCardUpgradeWarning.java

public class SdCardUpgradeWarning extends Activity implements View.OnClickListener {

    private static final String TAG = "SdCardUpgradeWarning";

    private static String updatePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/update.zip";
    private Button mCancle;
    private Button mConfirm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sdcardupgrade_warning);
        mCancle = (Button) findViewById(R.id.cancle);
        mCancle.setOnClickListener(this);
        mConfirm = (Button) findViewById(R.id.confirm);
        mConfirm.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.cancle:
                finish();
                break;
            case R.id.confirm:
                confirmUpdatePackageExist();
                break;

            default:
                break;
        }
    }

    public void confirmUpdatePackageExist() {
        File updatePackage = new File(updatePath);
        if (isFileExist(updatePackage)) {
            boolean isZipfileExist = updatePackage.exists();
            if (!isZipfileExist) {
                Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.update_package_not_found), Toast.LENGTH_LONG);
                toast.setGravity(0, 0, 100);
                toast.show();
            } else {
                Intent intent = new Intent();
                intent.setClass(this, SdCardUpgradeIntroduction.class);
                startActivity(intent);
            }

        } else {
            Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.sdcard_not_mounted), Toast.LENGTH_LONG);
            toast.setGravity(0, 0, 100);
            toast.show();
        }
    }

    public boolean isFileExist(File file) {
        if (file.exists()) {
            return true;
        } else {
            Log.d(TAG, "Update zip file not exist.");
            return false;
        }
    }

}
3.SdCardUpgradeIntroduction.java
public class SdCardUpgradeIntroduction extends Activity implements View.OnClickListener {

    private Button mcancle;
    private Button mconfirm;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.sdcardupgrade_introduction);

        mcancle=(Button)findViewById(R.id.cancle);
        mcancle.setOnClickListener(this);
        mconfirm=(Button)findViewById(R.id.confirm);
        mconfirm.setOnClickListener(this);
    }
    @Override
    public void onClick(View v){
        switch(v.getId()){
            case R.id.cancle:
                finish();
                break;

            case R.id.confirm:
                Intent intent = new Intent();
                intent.setClass(this, SdCardUpgradeProcess.class);
                startActivity(intent);
                break;

            default:
                break;
        }
    }

}
4.SdCardUpgradeProcess.java
public class SdCardUpgradeProcess extends Activity implements RecoverySystem.ProgressListener {
    private static final String TAG = "SdCardUpgradeProcess";
    private static final int VERIFY_COMPLETE = 70;
    private static final int INSTALL_COMPLETE  = 100;
    private static String updatePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/update.zip";

    private ProgressBar mProcessbar;
    private TextView mUpdateStep;
    private TextView mUpdateState;
    private TextView mNotify;
    private TextView sdcard_update_introduction_textview_one;
    private TextView sdcard_update_introduction_textview_two;
    private ImageView mCompleteImg;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.sdcardupgrade_processbar);

        mUpdateStep = (TextView)findViewById(R.id.step_number);
        mUpdateState = (TextView)findViewById(R.id.processbar_title);
        mNotify = (TextView)findViewById(R.id.update_notify);
        mCompleteImg = (ImageView)findViewById(R.id.update_complete);

        mProcessbar=(ProgressBar)findViewById(R.id.processbar);
        mProcessbar.setMax(110);
        mProcessbar.setProgress(0);
        mProcessbar.setIndeterminate(false);

        runnable.start();

    }
    Handler mHandler = new Handler(){
        public void handleMessage(Message msg) {

            mProcessbar.setProgress(msg.arg1);

            switch(msg.arg1){
                case VERIFY_COMPLETE:
                    mUpdateStep.setText(getString(R.string.the_next_step_number));
                    mUpdateState.setText(getString(R.string.install_process));
                    mNotify.setText("");
                    break;

                case INSTALL_COMPLETE:
                    mUpdateState.setText(getString(R.string.install_process_complete));
                    mNotify.setText(getString(R.string.restart));
                    mCompleteImg.setBackgroundResource(R.drawable.update_complete);
                    break;

                default:
                    break;
            }
        }
    };
    Thread runnable = new Thread(){

        @Override
        public void run() {
            Log.d(TAG, "Start update .............");
            File file = new File(updatePath);
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "SdCardUpgrade ProcessBar");
            try{
                wl.acquire();//升级保持亮屏状态
                RecoverySystem.verifyPackage(file, SdCardUpgradeProcess.this, null);
                Log.d(TAG,"Verify package complete.");
                RecoverySystem.installPackage(SdCardUpgradeProcess.this, file);

            }catch(Exception e){
                Log.e(TAG, e.getMessage(), e);

            }finally{
                wl.release();
            }
        }
    };

    @Override
    public void onProgress(int progress) {
        Log.d(TAG,"progress="+progress);
        Message msg = Message.obtain();
        msg.arg1 = progress;
        mHandler.sendMessage(msg);
    }
    @Override
    public void onBackPressed() {
        // TODO Auto-generated method stub
        System.exit(0);
    }
}
5.下面是三个布局文件

sdcardupgrade_warning.xml

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:id="@+id/sdCard_upgrade_textview_one"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/sdcard_upgrade_warning_title"
        android:textSize="22dp" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/sdcard_update_image_first"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/sdcard_upgrade_warning" />

        <TextView
            android:id="@+id/sdCard_upgrade_textview_two"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/sdcard_update_image_first"
            android:text="@string/sdcard_upgrade_warning_list_first"
            android:textSize="18dp" />

        <ImageView
            android:id="@+id/sdcard_update_image_second"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/sdCard_upgrade_textview_two"
            android:background="@drawable/sdcard_upgrade_warning" />

        <TextView
            android:id="@+id/sdCard_upgrade_textview_three"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/sdCard_upgrade_textview_two"
            android:layout_toRightOf="@id/sdcard_update_image_second"
            android:text="@string/sdcard_upgrade_warning_list_second"
            android:textSize="18dp" />

        <ImageView
            android:id="@+id/sdcard_update_image_third"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/sdCard_upgrade_textview_three"
            android:background="@drawable/sdcard_upgrade_warning" />

        <TextView
            android:id="@+id/sdCard_upgrade_textview_four"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/sdCard_upgrade_textview_three"
            android:layout_toRightOf="@id/sdcard_update_image_third"
            android:text="@string/sdcard_upgrade_warning_list_third"
            android:textSize="18dp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="bottom"
            android:orientation="horizontal">

            <Button
                android:id="@+id/cancle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="@string/sdcard_upgrade_cancle" />

            <Button
                android:id="@+id/confirm"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/cancle"
                android:layout_weight="1"
                android:gravity="center"
                android:text="@string/sdcard_upgrade_confirm" />
        </LinearLayout>
    </RelativeLayout>
</LinearLayout>
sdcardupgrade_introduction.xml

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:id="@+id/sdCard_upgrade_introduction_one"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/sdcard_upgrade_introduction"
        android:textSize="18dp" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="bottom"
        android:orientation="horizontal">

        <Button
            android:id="@+id/cancle"
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/sdcard_upgrade_cancle" />

        <Button
            android:id="@+id/confirm"
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/sdcard_upgrade_confirm" />
    </LinearLayout>
</LinearLayout>
sdcardupgrade_processbar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="36dp">

    <TextView
        android:id="@+id/processbar_step"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/sdcardupgrade_step_one"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/step_number"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/the_step_number"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/processbar_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/sdcardupgrade_title_one"
        android:textSize="35dp" />

    <ProgressBar
        android:id="@+id/processbar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="240dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="10dp"
        android:visibility="visible" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/update_complete"
            android:layout_width="45dp"
            android:layout_height="40dp"
            android:layout_gravity="center" />

        <TextView
            android:id="@+id/update_notify"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:padding="3dp"
            android:text="@string/update_introduction"
            android:textSize="20dp" />
    </LinearLayout>
</LinearLayout>
6.字符串资源文件

<resources>
    <string name="app_name">SdCardUpgrade</string>
    <string name="action_settings">Settings</string>
    <!-- Add for sdcard upgrade-->
    <string name="settings_storage_software_upgrade">SoftWare Upgrade</string>
    <string name="settings_storage_sdcard_upgrade">SD card Upgrade</string>
    <string name="sdcard_upgrade_warning_title">Warning</string>
    <string name="sdcard_upgrade_warning_list_first">During the upgrade,do not remove the battery,UIM card,and SD card.</string>
    <string name="sdcard_upgrade_warning_list_second">Make sure that the battery level is sufficent.</string>
    <string name="sdcard_upgrade_warning_list_third">You are recommanded to back up data to SD card before upgrade.</string>
    <string name="sdcard_upgrade_cancle">Cancle</string>
    <string name="sdcard_upgrade_confirm">Confirm</string>
    <string name="sdcard_upgrade_introduction">The upgrade takes about two minutes.Do not perform any operations during the upgrade.The upgrade application will automatically stop in 30s.</string>
    <string name="sdcardupgrade_step_one">Firmware update</string>
    <string name="sdcardupgrade_title_one">Unpacking...</string>
    <string name="update_introduction">The full update will take about 2 minutes.Please do not turn off the device during this period.</string>
    <string name="update_introduction_two">Do not turn off the device.</string>
    <string name="the_step_number">Step 1/2</string>
    <string name="the_next_step_number">Step 2/2</string>
    <string name="install_process">Install...</string>
    <string name="install_process_complete">Update Complete!</string>
    <string name="restart">restart...</string>
    <string name="update_package_not_found">No update package found!</string>
    <string name="sdcard_not_mounted">SD card not mounted!</string>
</resources>
注意:

    生成apk后需要使用平台签名文件进行签名,或者在Android.mk文件中配置签名属性并在源码中编译,否则无法运行。

三、最终效果图





  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值