一、制作OTA全量包
该文章的基础建立在已经搭建好aosp环境的基础上,未搭建好的可以看AOSP源码下载和编译
当前在andorid 8源码的基础上操作,手机为nexus 6p
执行以下命令:
build/envsetup.sh
lunch //然后选择你需要的配置(如28)
make otapackage -j8
执行完之后,全量包就是out/target/product/angler/aosp_angler-ota-eng.mo.zip
的zip压缩包;
可以通过卡刷,将全量包复制到sd卡,电源+上下键进入recovery模式
不管是线刷还是卡刷都是一样的原理,前期我们开发的使用还是使用fastboot flash方式最为方便
二、制作OTA增量包
Android增量的制作需要上一个旧的源码包和新的源码包,我们在制作全量包命令时就已经制作了源码包,它所在的目录为:
源码包路径:
out/target/product/angler/obj/PACKAGING/target_files_intermediates/aosp_angler-target_files-eng.mo.zip
全量包路径:
out/target/product/angler/aosp_angler-ota-eng.mo.zip
源码包的大小要比全量包大很多,系统一般使用的是全量包和增量包升级。
制作增量包
制作增量包我们首先要准备一个最新版本的源码包和上一个版本的源码包如old.Zip和new.zip。然后我们在根目录创建创建一个OTA/
文件夹,分别为将olde.zip和new.zip复制到该文件夹中,然后执行下面命令
./build/tools/releasetools/ota_from_target_files -i ~/OTA/old.zip ~/OTA/new.zip ~/OTA/update.zip
上面的命令
-
./build/tools/releasetools/ota_from_target_files
为谷歌为我们提供的一个用于生成增量包的脚本。 -
-i
后面分别为旧版本源码包
和新版本源码包
的文件路径,做好一个是生产的增量包路径。
执行上面的命令我们就会在根目录下的OTA文件夹下生产了一个update.zip增量包
``
三、Android代码调用升级
跟进上面的操作,全量升级包
或是增量升级包
都会得到update.zip
升级包。我们平时看到的系统升级,一般分为在线升级和离线升级;
- 在线升级:就是将
全量升级包
或是增量升级包
放在服务器上,根据自己的业务将其下载进行升级。 - 离线升级:需要将升级包烤包到sd卡中进行升级。
下面我们使用离线升级的方式,使用app(系统权限app)调用代码进行升级操作;
把update.zip
放在cache/update.zip
,否则会出现权限问题!
清单文件中添加权限
<manifest ...
android:sharedUserId="android.uid.system" //系签名要添加的标识
...>
<uses-permission android:name="android.permission.RECOVERY" />
<uses-permission android:name="android.permission.REBOOT" />
</manifest>
因为上面两个权限需要将应用做出系统及app才可以使用,因此需要系统签名
。文章的末尾的参考连接中有关于系统签名的实现方式。
获取升级包
/**
* 获取升级包
*
* @return 升级包file
*/
public File getUdapteFile() {
File updateFile = null;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String updatePath = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "update.zip";
updateFile = new File(updatePath);
boolean isExists = updateFile.exists();
LogHelper.getInstance().d("是否存在升级包:"+isExists);
if (isExists) {
return updateFile;
}
}
return updateFile;
}
校验和升级
/**
* 系统升级
*/
public void systemUpdate() {
File udapterFile = getUdapteFile();
try {
//签名校验
RecoverySystem.verifyPackage(udapterFile, new RecoverySystem.ProgressListener() {
@Override
public void onProgress(int progress) {
LogHelper.getInstance().d("签名校验进度:" + progress);
}
}, null);
//升级
RecoverySystem.installPackage(this, udapterFile);
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
上面的RecoverySystem.verifyPackage()
方法用于校验升级包的签名是否合法,我们在做升级名的时候make otapackage
命令执行完已经为我们签好了名,因此不需要在签名了。
注:在git网上看到了两个关于fota升级的项目:
- 项目一:https://github.com/momxmo/UI-Fota-Android6
这个项目使用OtaRecovery.java自定义命令行的方式,实际也是仿造系统RecoverySystem 的API底层实现来处理- 项目二:https://github.com/momxmo/Android_Fota
这个项目最终也是调用系统的RecoverySystem.installPackage(this, packageFile);升级
总结:
整个OTA升级过程遇到了很多问题。第一个,就是差分包建议提前进入recovery模式启动adb命令安装adb sideload <packname>
方式验证一下差分包是否正常,或者是否存在签名的问题,我整个测试的过程中,是没有有对差分包进行签名的;第二个,就是权限的问题,update.zip
增量包我放在/data/update.zip
目录下验证是提示权限问题,后来放到/cache/update.zip
下没这问题了,时间问题我就没去深究;
网友评论