最近在搞 Android A/B 分區(qū) OTA 升級(jí)踩官,手機(jī)方案公司出來(lái)之后就好久沒(méi)搞過(guò)源碼開(kāi)發(fā)了却桶,開(kāi)始以為挺簡(jiǎn)單的一個(gè)事,沒(méi)想到折騰了幾天,還好終于搞定颖系!
最開(kāi)始以為還是走 RecoverySystem.installPackage 這種方式嗅剖,確認(rèn)之后得用UpdateEngine方式了。
另外有點(diǎn)坑的是嘁扼,代碼調(diào)用其實(shí)就那么點(diǎn)信粮,但是參數(shù)之類(lèi)的很關(guān)鍵,還有權(quán)限也很關(guān)鍵趁啸,搬磚過(guò)來(lái)走不通强缘,我就是卡了2天,一些莫名的錯(cuò)誤不傅,沒(méi)法定位欺旧。
如:
ErrorCodeConstants.DOWNLOAD_TRANSFER_ERROR = 9
后面各種查資料,結(jié)合系統(tǒng)代碼蛤签,寫(xiě)了一個(gè)解析類(lèi) 只需傳入update.zip包(當(dāng)然也可以解壓之后再傳對(duì)應(yīng)的參數(shù))辞友,解析后升級(jí),爽的一批震肮。
需要注意的坑在代碼里也備注了称龙,有需要的碼友要注意下,特別是如果卡住了找不到原因所在的情況戳晌。
源碼APK我也放在csdn上了鲫尊,供參考。
下載鏈接 =====> 應(yīng)用層調(diào)用UpdateEngine代碼Apk源碼
調(diào)用代碼大致如下:
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:// 回調(diào)狀態(tài)沦偎,升級(jí)進(jìn)度
//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) {// 回調(diào)狀態(tài)
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");
}
}
相關(guān)代碼接口說(shuō)明如下
一疫向、framwork層 應(yīng)用接口
源代碼位置:framwork/base/core/java/android/os/UpdateEngine.java
framwork/base/core/java/android/os/UpdateEngineCallback.java
二、app應(yīng)用調(diào)取applyUpdate方法我這里只說(shuō)一下大致流程
當(dāng)然得系統(tǒng)權(quán)限的App了豪嚎,需要系統(tǒng)簽名搔驼,這些Api也是@SystemApi的
1、創(chuàng)建 UpdateEngineCallback 的對(duì)象 mUpdateEngineCallback
2侈询、創(chuàng)建 UpdateEngine 的對(duì)象 mUpdateEngine, 創(chuàng)建后服務(wù)開(kāi)啟
3舌涨、使用mUpdateEngine.bind(mUpdateEngineCallback) 因?yàn)閎ind方法時(shí)接受的callback對(duì)象,而我們創(chuàng)建的類(lèi)繼承了callback,傳入當(dāng)前類(lèi)的對(duì)象即可
4扔字、調(diào)用 applyPayload(String url,long offset,long size,String[] headerKeyValuePairs) 方法具體執(zhí)行升級(jí)
5囊嘉、在重寫(xiě)的onStatusUpdate(int status, float percent)方法中根據(jù)拿到的狀態(tài)執(zhí)行進(jìn)度邏輯
在重寫(xiě)的onPayloadApplicationComplete(int errorCode);方法中執(zhí)行升級(jí)完成后的邏輯