简单记录一下AndroidOTA升级。这个是Android标准的,也算是笔记简单了。
记录一下流程,和部分主要的代码,方便自己查阅。
正文
Android 原生也有自己升级的apk。
ASOP目录下 :\packages\apps\Car\SystemUpdater
UpdateParser.java是SystemUpdater中的代码。
UpdateParser.java
/** Parse an A/B update zip file. */ public class UpdateParser { private static final String TAG = OtaApp.TAG + "UpdateParser"; private static final String PAYLOAD_BIN_FILE = "payload.bin"; private static final String PAYLOAD_PROPERTIES = "payload_properties.txt"; private static final String FILE_URL_PREFIX = "file://"; private static final int ZIP_FILE_HEADER = 30; private UpdateParser() { } /** * Parse a zip file containing a system update and return a non null ParsedUpdate. */ @Nullable public static ParsedUpdate parse(@NonNull File file) throws IOException { Preconditions.checkNotNull(file); long payloadOffset = 0; long payloadSize = 0; boolean payloadFound = false; String[] props = null; try (ZipFile zipFile = new ZipFile(file)) { Enumeration<? extends ZipEntry> entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); long fileSize = entry.getCompressedSize(); if (!payloadFound) { payloadOffset += ZIP_FILE_HEADER + entry.getName().length(); if (entry.getExtra() != null) { payloadOffset += entry.getExtra().length; } } if (entry.isDirectory()) { continue; } else if (entry.getName().equals(PAYLOAD_BIN_FILE)) { payloadSize = fileSize; payloadFound = true; } else if (entry.getName().equals(PAYLOAD_PROPERTIES)) { try (BufferedReader buffer = new BufferedReader( new InputStreamReader(zipFile.getInputStream(entry)))) { props = buffer.lines().toArray(String[]::new); } } if (!payloadFound) { payloadOffset += fileSize; } Log.d(TAG, String.format("Entry %s", entry.getName())); } } return new ParsedUpdate(file, payloadOffset, payloadSize, props); } /** Information parsed from an update file. */ public static class ParsedUpdate { public final String mUrl; public final long mOffset; public final long mSize; public final String[] mProps; ParsedUpdate(File file, long offset, long size, String[] props) { mUrl = FILE_URL_PREFIX + file.getAbsolutePath(); mOffset = offset; mSize = size; mProps = props; } /** Verify the update information is correct. */ public boolean isValid() { return mOffset >= 0 && mSize > 0 && mProps != null; } @NonNull @Override public String toString() { return String.format(Locale.getDefault(), "ParsedUpdate: URL=%s, offset=%d, size=%s, props=%s", mUrl, mOffset, mSize, Arrays.toString(mProps)); } } }
这个也是核心代码。
MainActivity.java
部分代码
private void startUpdateOs(File zipFile) throws IOException { // 1. 解析升级包 UpdateParser.ParsedUpdate update = UpdateParser.parse(zipFile); if (update == null || !update.isValid()) { Log.e(TAG, "startUpdateOs Update package parsing failed or invalid"); return; } // 2. 创建 UpdateEngine 和 Callback UpdateEngine engine = new UpdateEngine(); UpdateEngineCallback callback = new UpdateEngineCallback() { @Override public void onStatusUpdate(int status, float percent) { // status 表示当前升级状态,percent 表示进度百分比 Log.i(TAG, "startUpdateOs OTA status: " + status + ", progress: " + percent); } @Override public void onPayloadApplicationComplete(int errorCode) { // errorCode 为 0 表示成功 } }; // 3. 绑定服务并应用升级 engine.bind(callback); engine.applyPayload(update.mUrl, update.mOffset, update.mSize, update.mProps); }
传入的是File。
这里要求是update.zip所在的绝对路径。比如
/storage/udisk/BiuOTA/update.zip
