最近在搞 Android A/B 分區 OTA 升級,手機方案公司出來之后就好久沒搞過源碼開發了,開始以為挺簡單的一個事,沒想到折騰了幾天,還好終於搞定!
最開始以為還是走 RecoverySystem.installPackage 這種方式,確認之后得用UpdateEngine方式了。
另外有點坑的是,代碼調用其實就那么點,但是參數之類的很關鍵,還有權限也很關鍵,搬磚過來走不通,我就是卡了2天,一些莫名的錯誤,沒法定位。
如:
ErrorCodeConstants.DOWNLOAD_TRANSFER_ERROR = 9
后面各種查資料,結合系統代碼,寫了一個解析類 只需傳入update.zip包(當然也可以解壓之后再傳對應的參數),解析后升級,爽的一批。
需要注意的坑在代碼里也備注了,有需要的碼友要注意下,特別是如果卡住了找不到原因所在的情況。
源碼APK我也放在csdn上了,供參考。
下載鏈接 =====> 應用層調用UpdateEngine代碼Apk源碼
調用代碼大致如下:
package com.system.ota;
import android.content.Context;
import android.os.UpdateEngine;
import android.os.UpdateEngineCallback;
import android.util.Log;
import java.net.MalformedURLException;
import java.text.DecimalFormat;
public class SystemUpdateManager {
private static final String TAG = "ota";
UpdateEngine mUpdateEngine;
public SystemUpdateManager(Context context) throws MalformedURLException {
mUpdateEngine = new UpdateEngine();
}
UpdateEngineCallback mUpdateEngineCallback = new UpdateEngineCallback() {
@Override
public void onStatusUpdate(int status, float percent) {
Log.d(TAG, "onStatusUpdate status: " + status);
switch (status) {
case UpdateEngine.UpdateStatusConstants.UPDATED_NEED_REBOOT:
rebootNow();
break;
case UpdateEngine.UpdateStatusConstants.DOWNLOADING:// 回調狀態,升級進度
//mProgressBar.setProgress((int) (percent * 100));
DecimalFormat df = new DecimalFormat("#");
String progress = df.format(percent * 100);
Log.d(TAG, "update progress: " + progress);
break;
default:
// noop
}
}
@Override
public void onPayloadApplicationComplete(int errorCode) {
Log.d(TAG, "onPayloadApplicationComplete errorCode=" + errorCode);
if (errorCode == UpdateEngine.ErrorCodeConstants.SUCCESS) {// 回調狀態
Log.d(TAG, "UPDATE SUCCESS!");
}
}
};
public void startUpdateSystem(UpdateParser.ParsedUpdate parsedUpdate) {
mUpdateEngine.bind(mUpdateEngineCallback);// 綁定callback
mUpdateEngine.applyPayload(
parsedUpdate.mUrl, parsedUpdate.mOffset, parsedUpdate.mSize, parsedUpdate.mProps);
}
/**
* Reboot the system.
*/
private void rebootNow() {
Log.e(TAG, "rebootNow");
}
}
相關代碼接口說明如下
一、framwork層 應用接口
源代碼位置:framwork/base/core/java/android/os/UpdateEngine.java
framwork/base/core/java/android/os/UpdateEngineCallback.java
二、app應用調取applyUpdate方法我這里只說一下大致流程
當然得系統權限的App了,需要系統簽名,這些Api也是@SystemApi的
1、創建 UpdateEngineCallback 的對象 mUpdateEngineCallback
2、創建 UpdateEngine 的對象 mUpdateEngine, 創建后服務開啟
3、使用mUpdateEngine.bind(mUpdateEngineCallback) 因為bind方法時接受的callback對象,而我們創建的類繼承了callback,傳入當前類的對象即可
4、調用 applyPayload(String url,long offset,long size,String[] headerKeyValuePairs) 方法具體執行升級
5、在重寫的onStatusUpdate(int status, float percent)方法中根據拿到的狀態執行進度邏輯
在重寫的onPayloadApplicationComplete(int errorCode);方法中執行升級完成后的邏輯