OTA线刷以及增量升级

安卓官方OTA文档

一、制作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