工控 APP 打包与预置:签名、系统应用、预装到 system/app 分区方法

📅 2026/7/26 18:45:10
工控 APP 打包与预置:签名、系统应用、预装到 system/app 分区方法
工控 APP 打包与预置签名、系统应用、预装到 system/app 分区方法你的工控APP装在/data分区用户一个恢复出厂就没了——要想永生就得住进system分区。一、APK签名机制1.1 为什么需要签名Android系统安装APK时会校验签名两个作用完整性验证确保APK没有被篡改身份识别相同签名的APP可以共享数据sharedUserId依赖签名一致性没有签名的APKAndroid拒绝安装。1.2 v1/v2/v3签名区别签名方案引入版本签名位置特点v1 (JAR签名)Android 1.0META-INF/ 目录基于JAR可被增量更新覆盖v2 (APK签名)Android 7.0APK文件末尾额外块全文件校验防篡改更强v3 (APK签名v3)Android 9.0APK文件末尾额外块支持密钥轮转签名密钥可更换工控建议固件预装APK用v1v2双签名兼容所有Android版本。Android 11 默认强制v2/v3但工控设备ROM版本跨度大从4.4到12都有双签名是安全选择。1.3 生成keystorekeytool-genkeypair-v\-keystoreindustrial.keystore\-aliasindustrial\-keyalgRSA\-keysize2048\-validity10000\-sigalgSHA256withRSA参数说明-validity 10000有效期10000天约27年工控设备不能让签名过期-keysize 2048密钥长度2048位是安全底线用此keystore在Gradle中签名android{signingConfigs{release{storeFilefile(industrial.keystore)storePasswordyour_passwordkeyAliasindustrialkeyPasswordyour_password}}buildTypes{release{signingConfig signingConfigs.release}}}二、普通应用 vs 系统应用2.1 核心区别维度普通应用/data/app系统应用/system/app安装位置/data/app//system/app/ 或 /system/priv-app/卸载可卸载无法通过常规方式卸载权限等级普通权限危险权限(需动态申请)可获得系统级权限signature更新方式应用商店/adb install只能通过固件升级或adb push覆盖恢复出厂会被清除保留system分区不受影响sharedUserId不生效除非系统签名可用android.uid.system获得系统权限工控核心诉求系统应用不会被恢复出厂设置清除且拥有更高权限。工控APP绝大多数场景都需要以系统应用身份运行。2.2 priv-app——特权应用Android 4.4 引入/system/priv-app/目录放入此目录的APP不仅能获得系统签名权限还能获得privileged级别权限如WRITE_SETTINGS、SET_DEBUG_APP等普通系统应用也拿不到的权限。/system/app/ → 系统应用普通系统权限 /system/priv-app/ → 特权系统应用最高权限等级三、系统签名获取方式3.1 方式一平台密钥签名最正统的方式——用设备厂商提供的平台密钥对APK签名# 用signapk.jar签名Android源码中的签名工具java-jarsignapk.jar\platform.x509.pem\platform.pk8\app-release-unsigned.apk\app-release-signed.apkplatform.pk8和platform.x509.pem是设备厂商的平台私钥和证书不同厂商密钥不同同一厂商不同产品线也可能不同。签名后配合android:sharedUserIdandroid.uid.systemAPP就运行在系统进程空间拥有全部系统权限。3.2 方式二将keystore转换为平台密钥格式如果你有platform.pk8和platform.x509.pem可以转换为Android Studio可用的keystore# pk8转pem私钥openssl pkcs8-inplatform.pk8-informDER-outformPEM\-outplatform.pem-nocrypt# 生成pkcs12格式keystoreopenssl pkcs12-export-inplatform.x509.pem\-inkeyplatform.pem\-outplatform.p12-nameplatform# pkcs12转jks keystorekeytool-importkeystore-deststorepassandroid\-destkeystoreplatform.keystore\-srckeystoreplatform.p12\-srcstorepassandroid-aliasplatform生成的platform.keystore可直接在Gradle中使用。3.3 方式三预装到system分区无需系统签名不声明sharedUserId仅通过push到/system/app/目录使APP成为系统应用。这种方式APP只能获得普通系统权限不能获得signature级权限。适用场景APP不需要系统级特权只需要恢复出厂不被清除。四、预装到system/app分区——三种方法4.1 方式一打包到固件推荐量产方案将APK放入Android源码树编译进system.img步骤1创建预置目录Android源码根目录/packages/apps/MyIndustrialApp/ ├── Android.mk ├── MyIndustrialApp.apk步骤2编写Android.mkLOCAL_PATH : $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE : MyIndustrialApp LOCAL_MODULE_CLASS : APPS LOCAL_MODULE_SUFFIX : $(COMMON_ANDROID_PACKAGE_SUFFIX) LOCAL_SRC_FILES : MyIndustrialApp.apk LOCAL_CERTIFICATE : platform # 用平台密钥签名 # LOCAL_CERTIFICATE : PRESIGNED # 如果APK已自行签名 include $(BUILD_PREBUILT)LOCAL_CERTIFICATE : platform表示编译系统会用平台密钥重新签名APK。步骤3配置产品mk文件在设备的device/vendor/product/product.mk中添加PRODUCT_PACKAGES MyIndustrialApp步骤4编译固件makesystemimage-j8APK会自动编译进system.img烧录固件后APP就在/system/app/MyIndustrialApp/目录中。4.2 方式二adb手动推送调试/小批量方案# 1. 获取root权限并remountadb root adb remount# 2. 推送APK到system分区adb push MyIndustrialApp.apk /system/app/MyIndustrialApp/# 3. 创建目录方式推荐更规范adb shellmkdir/system/app/MyIndustrialApp adb push MyIndustrialApp.apk /system/app/MyIndustrialApp/MyIndustrialApp.apk# 4. 重启让系统识别adbreboot注意adb remount需要root权限。部分设备的system分区是只读的需要先adb shell mount -o rw,remount /system。陷阱Android 9 的system分区可能采用A/B分区设计直接push修改的是当前活跃分区下次OTA更新可能被覆盖。量产必须走方式一。4.3 方式三通过recovery刷入适用于无法adb remount的场景如系统分区锁死步骤1创建刷机包结构update.zip/ ├── META-INF/ │ └── com/ │ └── google/ │ └── android/ │ ├── update-binary │ └── updater-script ├── system/ │ └── app/ │ └── MyIndustrialApp/ │ └── MyIndustrialApp.apk步骤2编写updater-scriptui_print(Installing MyIndustrialApp...);mount(ext4,EMMC,/dev/block/bootdevice/by-name/system,/system);package_extract_dir(system,/system);set_perm(0,0, 0644,/system/app/MyIndustrialApp/MyIndustrialApp.apk);unmount(/system);ui_print(Done!);步骤3签名zip并刷入# 签名刷机包java-jarsignapk.jar testkey.x509.pem testkey.pk8 update.zip update-signed.zip# 进入recovery模式刷入adbrebootrecovery# 或通过fastbootfastboot update update-signed.zip五、APK预置注意事项5.1 so库适配预装APK的native库.so架构必须与设备CPU架构匹配# 查看设备架构adb shell getprop ro.product.cpu.abi# 常见结果arm64-v8a, armeabi-v7aAPK中的so库需要放在正确目录/system/app/MyIndustrialApp/lib/arm64/ → arm64-v8a的so库 /system/app/MyIndustrialApp/lib/arm/ → armeabi-v7a的so库5.2 odex优化系统预装APP会在启动时进行dex优化生成odex文件加快首次启动速度。如果固件编译时已生成odexLOCAL_DEX_PREOPT : true则无需二次优化。调试阶段推送的APK首次启动会较慢系统在做dex2oat优化等一会儿就好。5.3 权限预配置系统预装APP的权限默认全部授权无需用户确认但部分危险权限在Android 6.0仍需要运行时申请。预装到system分区可以绕过部分限制但priv-app白名单机制/system/etc/permissions/privapp-permissions.xml可能拒绝某些特权!-- /system/etc/permissions/privapp-permissions-myapp.xml --permissionsprivapp-permissionspackagecom.example.industrialpermissionnameandroid.permission.WRITE_SETTINGS/permissionnameandroid.permission.SYSTEM_ALERT_WINDOW//privapp-permissions/permissions六、预装应用更新与卸载说明6.1 更新系统分区的APP不能通过常规adb install更新版本号冲突。更新方式重新push覆盖adb push new.apk /system/app/MyIndustrialApp/MyIndustrialApp.apk然后adb reboot固件升级新版固件包含新版APPOTA推送或手动烧录应用商店更新部分定制ROM允许通过应用商店覆盖更新系统APP更新装在/data分区优先级高于/system中的旧版本6.2 卸载# 临时卸载恢复出厂设置后会恢复adb shell pm uninstall-k--user0com.example.industrial# 永久卸载需要root删除system分区中的文件adb root adb remount adb shellrm-rf/system/app/MyIndustrialApp adbreboot-k参数保留数据缓存不加则彻底清除。永久卸载需要删除system分区中的物理文件。七、完整操作流程速查步骤操作命令1编译release APK./gradlew assembleRelease2用平台密钥签名java -jar signapk.jar platform.x509.pem platform.pk8 app.apk app-signed.apk3adb推送到systemadb push app-signed.apk /system/app/MyIndustrialApp/4重启设备adb reboot5验证安装adb shell pm list packages | grep industrial6验证权限adb shell dumpsys package com.example.industrial | grep grantedtrue把APP送进system分区它就跟固件绑定了命——恢复出厂不怕、权限等级拉满、开机自动就位。这是工控APP走向正式上岗的必经之路。