可以使用系統的API來實現系統更新。分兩種更新,non-streaming 和 streaming。non-streaming就是把更新包下載好,放到本地,然後執行更新。而streaming是爲了你的設備內存不夠,不能把更新包下載下來,使用的,url要用https:xxxxx而不是本地文件路徑。
你也可以參考源碼中的sample,/bootable/recovery/updater_sample
UpdateEngine這個是系統的API,如果你要在app中使用,只能用反射的方法,如果在源碼中使用,就可以直接用了。
public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) {
try {
mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
方法一 在app中用反射:
Class<?> UpdateEngineClass = Class.forName("android.os.UpdateEngine");//完整类名
Object UpdateEngine = UpdateEngineClass.newInstance();//获得实例
Method bind = UpdateEngineClass.getMethod("bind", UpdateEngineCallback.class);
bind.setAccessible(true);//调用方法前,设置访问标志
bind.invoke(UpdateEngine, callback);
Method applyPayload = UpdateEngineClass.getMethod("applyPayload", String.class, long.class, long.class, String[].class);//获得私有方法
applyPayload.setAccessible(true);//调用方法前,设置访问标志
applyPayload.invoke(UpdateEngine, "file://" + updateFilePath, offset, size, headerKeyValuePairs);//使用方法
這邊的callback你要自己寫,包名要和源碼中一樣,這樣就能編譯過。
這邊的url就是你OTA的路徑(也可以是https:xxxxxx),這邊還需要三個參數 offset , size , headerKeyValuePairs。可以通過下面的方法從更新包zip中獲取。
這邊的headerKeyValuePairs
* String[] pairs = { * "FILE_HASH=lURPCIkIAjtMOyB/EjQcl8zDzqtD6Ta3tJef6G/+z2k=", * "FILE_SIZE=871903868", * "METADATA_HASH=tBvj43QOB0Jn++JojcpVdbRLz0qdAuL+uTkSy7hokaw=", * "METADATA_SIZE=70604" * };
就是這樣的。filesize 就是size
private String[] headerKeyValuePairs = new String[4];
private String[] updateTemp1 = new String[MaxRow];
private String[] updateTemp2 = new String[MaxRow];
private String[] updateTemp3 = new String[MaxRow];
try {
i=0;
j=0;
InputStream in = new BufferedInputStream(new FileInputStream(file));
ZipInputStream zin = new ZipInputStream(in);
ZipEntry ze;
while ((ze = zin.getNextEntry()) != null) {
if (ze.isDirectory()) {
//Do nothing
} else {
if (ze.getName().contains("payload_properties.txt")) {
BufferedReader br = new BufferedReader(
new InputStreamReader(zin));
String line;
while ((line = br.readLine()) != null) {
headerKeyValuePairs[i] = line;
i++;
}
}
if (ze.getName().contains("metadata")) {
BufferedReader br = new BufferedReader(
new InputStreamReader(zin));
String line;
while ((line = br.readLine()) != null) {
if (i >= MaxRow) {
Log.i("OTA", "MaxRow is too small, Cannot get metadata total information");
break;
}
updateTemp1[j] = line;
j++;
}
}
}
}
zin.closeEntry();
zin.close();
readSize();
} catch (IOException e) {
e.printStackTrace();
}
private void readSize() {
for (int i = 0; i < updateTemp1.length; i++) {
if (updateTemp1[i].contains("ota-streaming-property-files")) {
updateTemp4 = updateTemp1[i];
break;
}
}
updateTemp2 = updateTemp4.split(",");
for (int i = 0; i < updateTemp2.length; i++) {
if (updateTemp2[i].contains("ota-streaming-property-files")) {
updateTemp4 = updateTemp2[i];
}
}
updateTemp3 = updateTemp4.split(":");
offset = Long.parseLong(updateTemp3[1]);
size = Long.parseLong(updateTemp3[2]);
}
方法二:
直接在源碼中使用,比較簡單。參數獲取都一樣,不說了。
至於streaming的方式去更新,使用也一樣,只是url變成了https:xxxxx,然後其它參數就要提前提供,可以用python去獲取,然後再告訴設備,然後設備再去update。