# PX3 地图拷贝功能流程图 ## 1. 文档说明 | 项目 | 内容 | |---|---| | 适用工程 | `YX_MainInterface_ZhongQi` | | 适用平台 | Android 4.4 PX3 车机 | | 新流程适用范围 | PX3 且 eMMC 判定为 32G 的设备 | | 旧设备兼容 | 非 32G 设备继续使用原 TF 卡地图流程 | | 文档依据 | 2026-09-09 当前代码实现 | 本文档只描述当前有效的 ZIP 地图方案。Map 分区正式文件直接位于 `/mnt/map` 根目录,不再使用旧路径 `/mnt/map/amapauto9/amapauto9.zip`。 ## 2. 固定路径 | 用途 | 当前路径 | |---|---| | U 盘地图压缩包 | `/mnt/usb_storage/amapauto9.zip` | | Map 导入临时文件 | `/mnt/map/amapauto9.zip.part` | | Map 正式地图压缩包 | `/mnt/map/amapauto9.zip` | | 内部地图目录 | `/mnt/sdcard/amapauto9/data/navi/compile_v2/chn` | | 内部语音目录 | `/mnt/sdcard/amapauto9/data/voice` | | 解压中标记 | `/mnt/sdcard/amapauto9/.yaxon_map_copying` | | 解压完成标记 | `/mnt/sdcard/amapauto9/.yaxon_map_complete` | | 旧设备 TF 卡地图 | `/mnt/external_sd0/amapauto9` | ZIP 内只处理以下两个目录: ```text amapauto9/data/navi/compile_v2/chn/... amapauto9/data/voice/... ``` ## 3. 总体流程 ```mermaid flowchart TD A["设备启动"] --> B["BSP 挂载 tfcard 分区到 /mnt/map"] B --> C["设置 /mnt/map 属主 system:system 和权限 0770"] C --> D{"/mnt/map 挂载成功且 system UID 可写?"} D -- "否" --> E["U盘导入和Map删除不可执行
提示检查Map分区挂载权限"] D -- "是" --> F["主界面和工程菜单可使用地图功能"] F --> G{"入口类型"} G -- "点击导航" --> H["执行导航入口流程"] G -- "进入工程模式" --> I["执行地图数据管理流程"] ``` ## 4. 导航入口流程 ```mermaid flowchart TD A0["主界面加载功能图标"] --> A1{"车辆配置是否有记录仪?"} A1 -- "否" --> A2["MAIN_ICON3或MAIN_ICON4
当前不显示导航图标"] A1 -- "是" --> A3["MAIN_ICON或MAIN_ICON2
显示导航图标"] A3 --> A["用户点击主界面导航图标"] A --> B{"是否为 PX3 + 32G eMMC?"} B -- "否" --> C{"/mnt/external_sd0/amapauto9 是否存在?"} C -- "是" --> D["启动高德导航"] C -- "否" --> E["提示插入含离线地图的 TF 卡"] B -- "是" --> F{"当前是否有地图任务正在执行?"} F -- "是" --> G["进入地图初始化页
恢复并显示后台任务状态"] F -- "否" --> H{"内部地图快速检查是否可用?"} H -- "是" --> D H -- "否" --> I["进入地图初始化页"] I --> J{"/mnt/map/amapauto9.zip 是否存在且非空?"} J -- "否" --> K["提示地图数据不可用
联系服务人员"] J -- "是" --> L["自动启动 Map 到 sdcard 解压任务"] L --> M["显示初始化提示、进度条和百分比"] M --> N{"任务结果"} N -- "成功" --> O["显示初始化完成
本次不直接打开导航"] N -- "失败" --> P["显示失败原因
允许重试或返回"] N -- "用户返回" --> Q["可选后台运行、停止任务或继续等待"] ``` 当前代码的 32G 判定流程: ```mermaid flowchart TD A["读取 /proc/partitions 中 mmcblk0 总块数"] --> B{"读取结果是否有效?"} B -- "是" --> C["块数乘1024,得到物理容量字节数"] B -- "否" --> D["读取 /sys/block/mmcblk0/size"] D --> E{"读取结果是否有效?"} E -- "是" --> F["扇区数乘512,得到物理容量字节数"] E -- "否" --> G["容量类型 UNKNOWN
不进入32G内部地图流程"] C --> H{"容量是否在 24GiB 到 40GiB 之间?"} F --> H H -- "是" --> I["判定为 EMMC_32G"] H -- "否" --> J["继续判断8G范围或判定UNKNOWN"] I --> K{"Build.PRODUCT、DEVICE或MODEL 是否为 rkpx3?"} K -- "是" --> L["启用32G内部地图流程"] K -- "否" --> M["不启用内部地图流程"] ``` 物理容量首次读取成功后会缓存在进程内,后续判断不重复读取块设备节点。 内部地图快速检查条件: 1. 不存在 `.yaxon_map_copying` 未完成标记。 2. `chn`、`voice` 目录存在。 3. 核心文件 `chn/a0/m1.ans` 非空。 4. `chn` 中存在区域目录,`voice` 中存在非空语音文件。 5. Map 正式 ZIP 存在时,完成标记必须匹配 ZIP 的文件大小和修改时间。 6. Map 正式 ZIP 不存在时,兼容旧设备已经存在的内部地图数据。 ## 5. 工程模式入口流程 ```mermaid flowchart TD A["进入工程模式"] --> B{"是否为 PX3 + 32G eMMC?"} B -- "否" --> C["不显示 地图数据管理 入口"] B -- "是" --> D["显示 地图数据管理 入口"] D --> E["进入地图数据管理页"] E --> F["后台检测 eMMC、U盘、Map压缩包和内部地图状态"] F --> G{"选择操作"} G --> H["从U盘导入到Map分区"] G --> I["删除Map分区地图"] G --> J["复制地图到sdcard目录"] G --> K["清除sdcard地图数据"] H --> L["执行U盘导入流程"] I --> M["二次确认后删除正式ZIP和part文件"] J --> N["执行Map解压流程"] K --> O["二次确认后执行内部地图清理流程"] L --> P["刷新页面状态"] M --> P N --> P O --> P ``` 工程页四项操作互相独立,不会自动串联。首次部署建议顺序为: ```text 必要时删除Map分区旧地图 -> 从U盘导入到Map分区 -> 复制地图到sdcard目录 ``` ## 6. 从 U 盘导入到 Map 分区 ```mermaid flowchart TD A["点击 从U盘导入到Map分区"] --> B{"设备是否为 PX3 + 32G?"} B -- "否" --> X1["提示仅支持32G设备"] B -- "是" --> C{"U盘是否已挂载?"} C -- "否" --> X2["提示先插入U盘"] C -- "是" --> D{"U盘根目录是否存在非空 amapauto9.zip?"} D -- "否" --> X3["提示未找到地图压缩包"] D -- "是" --> E{"Map正式ZIP或part是否已存在?"} E -- "是" --> X4["提示先删除Map分区旧数据"] E -- "否" --> F{"/mnt/map 是否为目录且可写?"} F -- "否" --> X5["提示Map分区不可写"] F -- "是" --> G["读取ZIP64中央目录"] G --> H{"ZIP结构、白名单目录和核心文件是否合法?"} H -- "否" --> X6["提示地图压缩包无效"] H -- "是" --> I{"Map剩余空间 >= ZIP大小 + 32MiB?"} I -- "否" --> X7["提示Map分区存储空间不足"] I -- "是" --> J["流式复制到 /mnt/map/amapauto9.zip.part"] J --> K["同步文件并校验源、目标大小"] K --> L["再次校验目标ZIP结构"] L --> M{"校验是否成功?"} M -- "否" --> N["删除part并返回失败"] M -- "是" --> O["同目录重命名为 /mnt/map/amapauto9.zip"] O --> P["显示导入成功"] J -. "取消、拔出U盘或I/O异常" .-> N ``` 说明:`.part` 是正在复制的临时文件,校验成功后直接重命名为正式 ZIP,不会在 Map 分区长期保留两份完整压缩包。 ## 7. Map 解压到 sdcard ```mermaid flowchart TD A["导航页自动初始化
或工程页点击复制地图到sdcard目录"] --> B["MapDataCopyService 接收任务"] B --> C{"是否已有地图任务运行?"} C -- "是" --> X1["拒绝重复启动并显示当前任务"] C -- "否" --> D["停止高德进程并等待文件释放"] D --> E{"高德是否已停止?"} E -- "否" --> X2["取消操作并提示失败"] E -- "是" --> F{"Map正式ZIP是否存在且非空?"} F -- "否" --> X3["提示Map地图源不存在"] F -- "是" --> G["读取ZIP64中央目录并生成白名单解压计划"] G --> H{"压缩格式、路径和必需条目是否合法?"} H -- "否" --> X4["提示压缩包无效"] H -- "是" --> I["只处理 chn 和 voice 文件"] I --> J{"是否为未完成恢复或ZIP身份变化?"} J -- "是" --> K["受管文件全部重新解压"] J -- "否" --> L["目标文件大小相同则跳过
缺失或大小不同则解压"] K --> M["计算本次所需新增空间"] L --> M M --> N{"sdcard剩余空间 >= 新增空间 + 300MiB?"} N -- "否" --> X5["提示内部存储空间不足"] N -- "是" --> O["写入 .yaxon_map_copying 标记并同步"] O --> P["按计划流式解压并实时校验条目大小和CRC"] P --> Q["每累计约512MiB执行批量sync"] Q --> R{"全部计划文件校验是否通过?"} R -- "否" --> X6["保留未完成状态
返回失败或允许重试"] R -- "是" --> S["写入 .yaxon_map_complete 完成标记"] S --> T["删除 .yaxon_map_copying 并最终sync"] T --> U["任务进度置为100%并提示成功"] U --> V["后台重启高德进程
使其重新初始化离线地图"] ``` 当前写入策略: - 新增文件直接写正式目标,写入失败时删除不完整文件。 - 覆盖已有文件时使用 `.yaxon_part` 临时文件,再重命名替换。 - 解压过程边写边计算 CRC;完成前进度最高显示 `99.9%`,最终成功后显示 `100%`。 - 当前差异计划以目标文件大小判断是否跳过;解压写入的文件会校验 ZIP 中记录的大小和 CRC。 ## 8. 删除 Map 分区地图 ```mermaid flowchart TD A["点击 删除Map分区地图"] --> B{"正式ZIP或part是否存在?"} B -- "否" --> C["提示Map分区无地图数据"] B -- "是" --> D["显示二次确认弹框"] D -- "取消" --> E["不做修改"] D -- "确认" --> F{"/mnt/map 是否可写?"} F -- "否" --> G["提示Map分区不可写"] F -- "是" --> H["删除 /mnt/map/amapauto9.zip"] H --> I["删除 /mnt/map/amapauto9.zip.part"] I --> J{"两个文件是否均已删除?"} J -- "是" --> K["提示删除成功"] J -- "否" --> L["提示删除失败"] ``` 该操作只删除地图正式 ZIP 和残留 `.part`,不会删除 `/mnt/map` 目录,也不会清理 Map 分区中的其他文件。 ## 9. 清除 sdcard 地图数据 ```mermaid flowchart TD A["点击 清除sdcard地图数据"] --> B{"是否存在受管地图或语音数据?"} B -- "否" --> C["提示sdcard无地图数据"] B -- "是" --> D["显示慎重操作二次确认弹框"] D -- "取消" --> E["不做修改"] D -- "确认" --> F["停止高德进程并等待文件释放"] F --> G["写入未完成标记并同步"] G --> H["清空 chn 目录内容
保留 chn 目录本身"] H --> I["清理 voice 中可重新导入的数据
保留 voice 目录本身和指定配置"] I --> J["删除完成标记"] J --> K{"清理是否全部成功?"} K -- "否" --> L["保留未完成状态并提示失败"] K -- "是" --> M["删除未完成标记并最终sync"] M --> N["提示清理成功"] ``` 必须保留的语音内容: ```text /mnt/sdcard/amapauto9/data/voice/voice_conf /mnt/sdcard/amapauto9/data/voice/common.irf /mnt/sdcard/amapauto9/data/voice/isstts.cfg /mnt/sdcard/amapauto9/data/voice/xiaoyan.irf ``` ## 10. 后台任务和页面交互 ```mermaid flowchart TD A["Activity 发起地图操作"] --> B["绑定同进程 MapDataCopyService"] B --> C["Service 保证同一时刻只有一个地图任务"] C --> D["MapDataCopyManager 在工作线程执行文件操作"] D --> E["Service 保存操作类型、进度、字节数和结果快照"] E --> F{"用户操作"} F -- "停留页面" --> G["页面持续刷新进度和提示"] F -- "按Home" --> H["Activity离开,Service继续后台执行"] F -- "再次进入" --> I["重新绑定Service并恢复当前快照"] F -- "按返回" --> J["弹框选择后台运行、停止任务或继续等待"] D --> K{"任务完成时页面是否绑定?"} K -- "是" --> L["页面显示结果弹框并刷新状态"] K -- "否" --> M["Service 使用Toast提示后台结果"] ``` 页面进度回调按当前交互约定节流,最多约每 `500ms` 更新一次,减少主线程刷新开销。 ## 11. 工程页状态显示 ```mermaid flowchart LR A["Map分区状态"] --> A1["无数据
正式ZIP和part均不存在"] A --> A2["数据不完整
存在part或正式ZIP小于7GiB"] A --> A3["数据完整
正式ZIP不小于7GiB且无part"] B["内部地图状态"] --> B1["无数据
chn和voice无受管数据"] B --> B2["数据不完整
有未完成标记或受管数据小于10GiB"] B --> B3["数据完整
无未完成标记且受管数据不小于10GiB"] ``` 以上三态用于工程页面快速展示,不替代实际导入、解压时的 ZIP 结构、空间、文件大小和 CRC 校验。 ## 12. BSP 前置条件与验证边界 BSP 侧目标启动顺序: ```rc mount ext4 /dev/block/platform/emmc/by-name/tfcard /mnt/map wait noatime nodiratime nosuid nodev noexec noauto_da_alloc,discard chown system system /mnt/map chmod 0770 /mnt/map ``` ```mermaid flowchart TD A["编译包含BSP修改的固件"] --> B["烧录boot或完整固件"] B --> C["重启设备"] C --> D["检查 /proc/mounts 中 /mnt/map 挂载来源和rw状态"] D --> E["检查 ls -ld /mnt/map 的属主和权限"] E --> F["使用系统应用执行U盘导入和删除"] F --> G["重启后再次复测,确认权限持续有效"] ``` 截至 2026-09-09,本次可访问的 BSP 文件 `Z:\znzc\003_zhongqi\android4.4_rkpx3_zhongqi_pro\device\rockchip\rksdk\ZQ_PRO_32G\ZQ_PRO_32G_init.rc` 仍保留两条 `/mnt/map` 挂载和 `start chmodmap`,尚未呈现上面的目标顺序。因此这里描述的是应用正常工作的前置要求,不表示该 BSP 修改已经进入源码或固件。 BSP 修改是否进入最终镜像、设备重启后 `/mnt/map` 是否仍可写,以及完整地图导入和解压结果,均必须以编译产物和真机日志为准。