RK3326 android10.0(Q) OTA 实战

简介: RK3326 android10.0(Q) OTA 实战

编译指令


发布一个固件正确的顺序

1、make -j32

2、make otapackage -j32

3、./mkimage.sh ota

4、./build.sh -u

或者直接执行

make -j32 && make otapackage -j32 && ./mkimage.sh ota && ./build.sh -u


拷贝 rockdev\Image-RK3326Box\update.img 作为发放烧写软件包


直接用 AndroidTool_Release 烧写固件即可


整包升级


拷贝 \out\target\product\RK3326Box\RK3326Box-ota-eng.zip 作为完整升级包,


重命名为 update.zip 拷贝到设备SDCard卡根目录重启,RKUpdateService-box 应用会弹框提示升级


差分包升级


拷贝 out\target\product\RK3326Box\obj\PACKAGING\target_files_intermediates\RK3326Box-target_files-eng.zip

为 V1.zip,作为 V1 版本的基础素材包备用,拷贝至源码根目录


修改kernel、package等 新版本修改内容后再次执行编译指令


make -j32 && make otapackage -j32 && ./mkimage.sh ota && ./build.sh -u


拷贝 out\target\product\RK3326Box\obj\PACKAGING\target_files_intermediates\RK3326Box-target_files-eng.zip

为 V2.zip,作为 V2 版本的基础素材包备用,拷贝至源码根目录


编译生成差分包指令


./build/tools/releasetools/ota_from_target_files -v -i V1.zip  --block  -p out/host/linux-x86 -k build/target/product/security/testkey V2.zip  update.zip


更目录下的 update.zip 就是最终的差分升级包


生成差异包命令格式:


ota_from_target_files


-v -i 用于比较的前一个 target file


–block 使用 block 方式进行 OTA 升级,Android 版本>=7.1 时需加上这个参数


-p host 主机编译环境


-k 打包密钥 用于比较的后一个 target file 生成的 ota 差异包


调用系统升级API RecoverySystem.installPackage


SystemUpgradeHelper.java

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import android.R.string;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RecoverySystem;
import android.os.RemoteException;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import android.os.ServiceManager;
public class SystemUpgradeHelper {
  private Context context;
  private ProgressDialog verifyPackageProgressDialog = null;
  private String internalSdPath = "/data/media/";
  private File otaFile = null;
  private String TAG = new String("SystemUpgradeHelper:");
  public SystemUpgradeHelper(Context context, File file) {
    this.context = context;
    verifyPackageProgressDialog = new ProgressDialog(context);
    verifyPackageProgressDialog
        .setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    verifyPackageProgressDialog.setTitle(context
        .getString(R.string.txtVerifying));
    verifyPackageProgressDialog.setMessage(context
        .getString(R.string.txtVerifyWarning));
    verifyPackageProgressDialog.setMax(100);
    verifyPackageProgressDialog.setProgress(0);
    verifyPackageProgressDialog.setSecondaryProgress(0);
    verifyPackageProgressDialog.setIndeterminate(false);
    verifyPackageProgressDialog.setCancelable(false);
    if (file == null) {
      this.otaFile = new File(internalSdPath + "/update.zip");
    } else {
      this.otaFile = file;
    }
  }
  Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
      String msg_buf = null;
      switch (msg.what) {
        case 1:
          msg_buf = context.getString(R.string.txtRamFull);
          break;
        case 2:
          msg_buf = context.getString(R.string.txtUpgradeFail);
          break;
        case 3:
          msg_buf = context.getString(R.string.txtFileNotExist);
          break;
        case 4:
          msg_buf = context.getString(R.string.txtVerifyFail);
          break;
        default:
          break;
      }
      if (msg_buf != null)
        Toast.makeText(context, msg_buf, Toast.LENGTH_SHORT).show();
      super.handleMessage(msg);
    }
  };
  public void excuteUpdateZip() {
    final Message msg = new Message();
    msg.what = 0;
    verifyPackageProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    verifyPackageProgressDialog.show();
    new Thread() {
      public void run() {
        try {
          Thread.sleep(3000);
          onConfirmUpdate();
        } catch (Exception ex) {
          verifyPackageProgressDialog.dismiss();
          msg.what = 1;
          mHandler.sendMessage(msg);
          Log.i(TAG, "Start Thread Error", ex);
        }
      }
      private void onConfirmUpdate() {
        try {
          RecoverySystem.verifyPackage(otaFile,
              new RecoverySystem.ProgressListener() {
                @Override
                public void onProgress(int progress) {
                  verifyPackageProgressDialog.setProgress(progress);
                }
              }, null);
          Log.i(TAG, "verifyPackage is completed and it ok");
          try {
            Log.i(TAG, "It will install package");
            RecoverySystem.installPackage(context, otaFile);
          } catch (Exception e) {
            e.printStackTrace();
            Log.i(TAG, "installPackage Error", e);
            msg.what = 2;
            mHandler.sendMessage(msg);
          }
        } catch (IOException e) {
          verifyPackageProgressDialog.dismiss();
          e.printStackTrace();
          msg.what = 3;
          mHandler.sendMessage(msg);
        } catch (GeneralSecurityException e) {
          verifyPackageProgressDialog.dismiss();
          e.printStackTrace();
          msg.what = 4;
          mHandler.sendMessage(msg);
        }
      }
    }.start();
  }
}

错误排查


image.png


完整包并未遇到该问题


在升级差分包时,出现了上图所示的错误


错误代码


E3001 this device has unknown/RK3326Box/…:userdebug/test-keys


E:Error in @/cache/recovery/block.map(status 7)


开始其实提示的是 E3001 this device has unknown/RK3326Box/…:userdebug/release-keys


去签名文件夹下中寻找 \build\target\product\security 确实没有 releasekey 相关


于是猜想和这里有关系,修改编译使用 test-keys


build/make/core/Makefile

 ifeq ($(TARGET_BUILD_VARIANT),eng)
 BUILD_KEYS := test-keys
 else
-BUILD_KEYS := release-keys
+# BUILD_KEYS := release-keys
+BUILD_KEYS := test-keys
 endif
 BUILD_VERSION_TAGS += $(BUILD_KEYS)



编译后可以通过 out\target\product\RK3326Box\system\build.prop 文件中 ro.system.build.tags=test-keys 确认


再次烧写ota升级验证,发现问题依旧,仔细品了品错误提示后发现 build fingerprint 这个关键字


机智的我立马去和 8.0 的 build.prop 进行了对比,最终发现差异


Q 版本


ro.system.build.fingerprint=rockchip/RK3326Box/RK3326Box:10/QQ2A.200501.001.B3/09021634:userdebug/test-keys


O版本

ro.build.fingerprint=rockchip/rk3288/rk3288:8.1.0/OPM8.190305.001/133946:userdebug/test-keys


Q版本中不存在 ro.build.fingerprint 字段,会不会和这有关系呢?先加上试试吧


搜索 ro.system.build.fingerprin 发现在 build/make/tools/buildinfo_common.sh 中进行写入


我们新增一条 ro.build.fingerprint

+++ b/build/make/tools/buildinfo_common.sh
@@ -13,6 +13,7 @@ echo "# autogenerated by $0"
 echo "ro.${partition}.build.date=`$DATE`"
 echo "ro.${partition}.build.date.utc=`$DATE +%s`"
 echo "ro.${partition}.build.fingerprint=$BUILD_FINGERPRINT"
+echo "ro.build.fingerprint=$BUILD_FINGERPRINT"
 echo "ro.${partition}.build.id=$BUILD_ID"
 echo "ro.${partition}.build.tags=$BUILD_VERSION_TAGS"
 echo "ro.${partition}.build.type=$TARGET_BUILD_TYPE"


再次重新编译烧写ota问题解决,升级成功啦!


参考文章


OTA升级失败排查

Android系统更新防互刷功能实现与分析

目录
相关文章
|
20天前
|
存储 消息中间件 人工智能
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
56 3
|
20天前
|
存储 消息中间件 人工智能
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
100 10
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
|
20天前
|
存储 消息中间件 人工智能
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
65 11
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
|
20天前
|
XML 存储 Java
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
55 3
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
|
20天前
|
存储 消息中间件 人工智能
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
52 4
|
20天前
|
存储 API Android开发
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
77 4
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
|
20天前
|
XML 编解码 Android开发
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
53 0
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
|
27天前
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
97 6
|
7月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
1409 77
|
5月前
|
Android开发 开发者
Android企业级实战-界面篇-3
本文是《Android企业级实战-界面篇》系列的第三篇,主要介绍分割线和条形跳转框的实现方法,二者常用于设置和个人中心界面。文章通过具体代码示例展示了如何实现这两种UI组件,并提供了效果图。实现前需准备`dimens.xml`、`ids.xml`、`colors.xml`等文件,部分资源可参考系列第一、二篇文章。代码中详细说明了布局文件的配置,如分割线的样式定义和条形跳转框的组件组合,帮助开发者快速上手并应用于实际项目中。

热门文章

最新文章