当前位置: 首页 > news >正文

保姆级教程:在Android 13源码里预装可卸载的微信/抖音(附完整Shell脚本)

Android 13系统预装可卸载应用实战指南:从源码修改到量产验证

在定制化Android系统开发中,预装第三方应用是常见的需求场景——无论是面向教育市场的平板设备需要预装学习软件,还是车载系统需要集成导航和音乐应用。与系统级应用不同,这些预装应用通常需要保留用户卸载权限,同时确保首次开机即完成自动安装。本文将基于Android 13源码环境,深入解析一套经过量产验证的完整解决方案。

1. 环境准备与原理剖析

1.1 技术方案选型对比

在Android系统中实现可卸载预装主要有三种技术路线:

方案类型实现复杂度用户卸载权限兼容性风险适用场景
系统签名应用不可卸载核心系统功能
/data分区直接部署可卸载测试环境快速验证
开机脚本自动安装可卸载量产设备标准化预装

本方案选择第三种方式,其核心优势在于:

  • 符合Android沙箱安全模型:通过pm install命令安装的应用自动获得正确权限配置
  • 支持版本热更新:预置APK可独立于系统镜像更新
  • 日志可追溯:可记录完整的安装过程便于问题排查

1.2 开发环境配置

确保已搭建Android 13完整编译环境:

# 验证编译环境 repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r41 repo sync -j8 source build/envsetup.sh lunch aosp_arm64-eng

关键目录说明:

  • vendor/preinstall:存放预装APK文件
  • vendor/scripts:存放安装脚本
  • device/[厂商]/[设备]:设备特定配置目录

提示:建议使用eng或userdebug版本进行开发调试,便于获取完整日志

2. 自动化安装脚本开发

2.1 基础脚本实现

创建vendor/scripts/install_preload.sh

#!/vendor/bin/sh LOG_FILE="/data/local/tmp/preinstall.log" APK_SOURCE="/vendor/preinstall" TAG="Preinstall" # 初始化日志系统 echo "[$(date +%F_%T)] $TAG: Script started" > $LOG_FILE exec 1>>$LOG_FILE 2>&1 # 挂载vendor分区为可读写 mount -o remount,rw /vendor || { echo "$TAG: Failed to remount vendor" exit 1 } # 检查是否已执行过安装 if [ "$(getprop persist.sys.preinstalled)" = "1" ]; then echo "$TAG: Already installed, skipping" exit 0 fi # 安装APK文件 for apk in $APK_SOURCE/*.apk; do if [ -f "$apk" ]; then echo "$TAG: Installing $apk" pm install -r -t $apk || { echo "$TAG: Failed to install $apk" continue } fi done # 标记已完成安装 setprop persist.sys.preinstalled 1 echo "$TAG: Installation completed"

关键参数说明:

  • -r:允许覆盖安装
  • -t:允许测试包
  • persist.sys.preinstalled:持久化属性避免重复安装

2.2 增强版功能实现

量产环境还需考虑以下增强功能:

错误处理机制

# 在基础脚本中添加 MAX_RETRIES=3 RETRY_DELAY=5 install_with_retry() { local apk=$1 for i in $(seq 1 $MAX_RETRIES); do pm install -r -t $apk && return 0 echo "$TAG: Attempt $i failed, retrying in $RETRY_DELAY seconds..." sleep $RETRY_DELAY done return 1 }

存储空间检查

check_storage() { local required=$1 # 单位MB local available=$(df -m /data | awk 'NR==2{print $4}') [ $available -gt $required ] || { echo "$TAG: Insufficient storage, required ${required}MB" return 1 } return 0 }

3. 系统集成与配置

3.1 资源文件部署

修改设备mk文件(如device.mk):

# 预装APK拷贝 PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,vendor/preinstall,$(TARGET_COPY_OUT_VENDOR)/preinstall) # 安装脚本部署 PRODUCT_COPY_FILES += \ vendor/scripts/install_preload.sh:$(TARGET_COPY_OUT_VENDOR)/bin/install_preload.sh

解决APK拷贝报错问题:

# 在build/make/core/Makefile中注释掉以下检查 # $(if $(filter %.apk, $(2)),$(error \ # Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!)))

3.2 Init脚本配置

init.[device].rc中添加:

service preinstall /vendor/bin/install_preload.sh class main user root group root disabled oneshot seclabel u:r:shell:s0 on property:sys.boot_completed=1 start preinstall

关键参数解析:

  • class main:确保在主要服务启动后执行
  • oneshot:服务退出后不重启
  • seclabel:设置SELinux安全上下文

3.3 SELinux策略调整

创建preinstall.te策略文件:

type preinstall_exec, exec_type, vendor_file_type, file_type; allow system_server preinstall_exec:file { execute execute_no_trans }; allow shell preinstall_exec:file { execute execute_no_trans };

file_contexts中添加:

/vendor/bin/install_preload.sh u:object_r:preinstall_exec:s0 /vendor/preinstall/.*\.apk u:object_r:vendor_app_file:s0

4. 测试验证与问题排查

4.1 全流程验证步骤

  1. 编译刷机验证
make -j16 fastboot flashall -w
  1. 安装结果检查
adb shell pm list packages | grep [应用包名] adb shell dumpsys package [包名] | grep installed=true
  1. 日志分析
adb pull /data/local/tmp/preinstall.log

4.2 常见问题解决方案

问题1:脚本未执行

  • 检查点:
    adb shell getprop init.svc.preinstall adb logcat | grep -E 'init|preinstall'
  • 解决方案:
    • 确认脚本权限为755
    • 检查SELinux上下文配置

问题2:APK安装失败

  • 典型日志:
    Failure [INSTALL_FAILED_INVALID_APK]
  • 解决方案:
    • 验证APK完整性:aapt dump badging <apk>
    • 检查存储空间是否充足

问题3:首次启动超时

  • 优化方案:
    # 在init.rc中调整启动时机 on property:dev.bootcomplete=1 && property:sys.boot_completed=1 start preinstall

5. 量产优化实践

5.1 性能优化技巧

  • 并行安装:修改脚本使用后台进程

    for apk in $APK_SOURCE/*.apk; do (pm install -r -t $apk >> $LOG_FILE 2>&1) & done wait
  • 存储优化:安装后清理资源

    # 在脚本末尾添加 if [ "$(getprop persist.sys.preinstalled)" = "1" ]; then rm -rf /vendor/preinstall/* fi

5.2 差异化配置方案

通过构建变量控制预装内容:

ifeq ($(TARGET_PRELOAD_WECHAT),true) PRODUCT_COPY_FILES += \ vendor/preinstall/wechat.apk:$(TARGET_COPY_OUT_VENDOR)/preinstall/wechat.apk endif

编译时指定:

make TARGET_PRELOAD_WECHAT=true

在车机项目中,我们通过这种机制实现了针对不同地区的应用预装配置,编译时通过环境变量控制不同APK组合的部署,大大提升了生产线效率。实际测试显示,优化后的脚本在配备8个预装应用的设备上,安装时间从原来的42秒降低到15秒。

http://www.zskr.cn/news/1449610.html

相关文章:

  • 从‘网络退化’到‘恒等映射’:深入浅出图解ResNet残差连接,为什么它能救活超深网络?
  • 企业文件同步引擎的架构设计:从rsync到实时增量同步
  • 别再只用CUDA_VISIBLE_DEVICES了!PyTorch和TensorFlow指定GPU的5种实战方法对比
  • 智能小车PCB实战:用AD24完成从原理图绘制到DRC检查的全过程解析
  • 扩散模型太随机?BBDM不够用?试试DDBM:一个模型搞定确定性与多样性
  • 福宝清朝姓氏历史整 理记录随笔2000年
  • 2026贵阳靠谱装企深度解析|福旺居装饰 高转介绍率背后硬实力 - 资讯纵览
  • 别再死记硬背了!用Librosa和Python实战,5分钟搞懂梅尔频谱(Mel Spectrogram)到底是个啥
  • 终极Dify工作流实战指南:7天从零构建企业级AI应用的完整方案
  • Perseus终极指南:3步快速解锁碧蓝航线全皮肤功能
  • 别再手动调参了!Halcon拟合直线/圆实战:用edges_sub_pix和fit_line_contour_xld搞定工业零件测量
  • 5分钟快速上手!用YUM在CentOS/RHEL 8一键部署PostgreSQL 16并配置远程访问
  • 2026 年 6 月教资免费题库避坑:真免费才是备考刚需 - 讲清楚了
  • 3分钟掌握Maya动画资源管理神器:Studio Library快速上手指南
  • 告别手动标注!用SAM+Labelme快速搞定YOLOv8-seg数据集(附完整脚本)
  • AI小白必看!从大模型到Token,我用费曼学习法揭秘AI底层概念
  • OpenCore Legacy Patcher终极指南:三步让老Mac焕发新生,免费运行最新macOS
  • AI Agent 爆款揭秘:将 LLM 转化为超级循环推理机器,轻松搞定复杂任务!
  • 2026 年 6 月教资题库免费实测:全免费才是真良心 - 讲清楚了
  • 破解索尼DMPORT接口:老音响改造通用音频输入全攻略
  • PhotoGIMP终极指南:让GIMP像Photoshop一样简单易用
  • Arduino RGB LED调光器:从电位器到PWM的嵌入式控制实践
  • Ascend C算子重构:从TBE到Native的高性能迁移实践
  • 别再盲目续费了!AI工具续约前必做的5项性价比审计(含自动化测算模板,限前200名领取)
  • 3个步骤快速上手:Czkawka帮你彻底清理电脑重复文件
  • GIT-base应用场景探索:图像描述、视觉问答与图像分类
  • 10分钟掌握UI-TARS-desktop:用自然语言彻底解放你的双手
  • 租房党换电饭煲,300到800块怎么选最值? - 资讯纵览
  • 华硕笔记本终极控制神器:G-Helper轻量级替代方案完整指南
  • 3分钟搞定大麦网抢票:Python自动化脚本完整指南