【免费下载链接】Vela
Maps and turn-by-turn navigation for Android without Google Play Services: the best of open map data, with Google lookups by choice. Runs on degoogled phones and can avoid Flock cameras
Vela 是一款专为无 Google Play 服务(degoogled)Android 手机打造的地图与逐路口导航应用,它以开放地图数据打底,并允许你按需查询 Google 的地点数据。由于 Vela 直接以"桌面浏览器"身份请求 google.com,Google 页面结构一变、解析就可能失效——而 Vela 的答案是一套签名 calibration 远程自愈机制:把易漂移的请求模板、字段路径、浏览器指纹外置成calibration.json,配合 ECDSA 签名下发,用户无需更新 APK 就能修复故障。
为什么需要"远程自愈"?
Vela 的评分、营业时间、照片、评论、热门时间、路线流量等数据,都来自 Google 的公开网页接口:手机伪装成一台桌面 Chrome 浏览器去问 google.com,然后自己解析答案(类似 NewPipe 之于 YouTube)。这条链路有三个天然脆弱点:
- 响应结构漂移:Google 把某个字段从
[1][105]挪到[1][72]——真实案例是预览照片块,漂移后发现时所有地点瞬间失去照片条(见 Calibration.kt 的注释); - 接口下线:例如 2026-10-05 起 Street View 的旧元数据接口被 Google 宣布"decommissioned",官方自己的请求改成了 JSON 请求体(见 Calibration.kt);
- 浏览器指纹过期:Chrome 大约每 4 周发一个稳定版,编译进 APK 的 User-Agent 按构造就是过期的;而 Google 会给不同浏览器世代下发不同响应结构。
走应用商店发版修复,周期以天计。Vela 的选择是一次签名推送,两三次启动内全员生效(项目注释称之为 "push out the scraping")。
自愈的载体:calibration.json 里装了什么
仓库根目录下的 calibration.json(当前 version 已迭代到 27)就是整个"药箱",字段大致分五类:
| 类别 | 字段示例 | 修复什么 |
|---|---|---|
| 请求与响应形状 | searchEndpoint、searchPb、paths、directionsPaths | 接口 URL、请求模板、解析器读取的位置索引 |
| 浏览器身份 | userAgent、secChUa、chromeFullVersion | 跟进 Chrome 大版本,避免指纹过期 |
| 词条表 | statusClosedWords、transitCategoryWords、reviewSelectors | 多语言营业状态词、评论页 CSS 选择器轮换 |
| 车队默认值 | defaultVoiceId、defaultMapPalette、tuning | 默认语音、地图配色、缩放等数字旋钮 |
| 用户通知与补丁代码 | notices、transformsJs | "搜索暂时故障、修复中"公告;沙箱 JS 解析补丁 |
关键的宽容解析逻辑在 CalibrationStore.parseBundle:逐字段读取,缺失或畸形字段回退到编译进 APK 的Calibration.DEFAULT;位置路径表则逐 key 合并覆盖——所以一次推送只需改动漂移的那一个字段,老字段完全不动。
三道安全闸门:为什么"签名"是这套机制的前提
能远程下发配置甚至解析代码,最大风险是被篡改后把用户请求重定向到攻击者服务器。Vela 在 CalibrationStore.refresh 中设置了三道闸门,三者同时满足才采纳远端包:
- 签名验证:对文件内容做 ECDSA(P-256 / SHA-256)分离签名验证(BundleSignature.kt),公钥 PINNED_PUBLIC_KEY 内嵌在 APK 里;私钥存在维护者本地
~/.vela-signing/目录,绝不入库。这意味着只有私钥持有者能推送配置、公告乃至解析补丁; - 主机白名单:所有 endpoint 的 host 必须落在
ALLOWED_HOSTS(www.google.com/google.com)——签名再"正确"的文件,也不能把搜索、路线、评论指到任何别处; - 版本号更高:远端
version必须大于当前生效版本(编译默认值为 1,任何已发布包天然胜出)。
连本地磁盘缓存都会重新验签(loadCached):被篡改、或来自旧版未签名构建的缓存,直接回退到内置默认值。因此应用永远以一套可工作的配置启动,完全离线也不受影响。
一次完整修复的发布流程
对维护者而言,"不发版修复"的完整动作只有三步:
- 编辑 calibration.json:改掉漂移的字段,把
"version"加一; - 运行 sign-calibration.sh:用私钥生成
calibration.json.sig(脚本自带验证,验不过会拒绝提交); - 两个文件一起提交到 main 分支。
之后每台用户手机启动时(不阻塞任何界面),按"上次推送告知的位置 → 编译进包的位置 → 官网镜像"的候选地址列表拉取文件与签名(见 refresh 注释);验签通过即静默生效。官方文档把整套流程称为 "signed calibration bundle",完整原理见 docs/book/07-talking-to-google.md。
还有一个贴心的细节:notices字段(Notice.kt)允许维护者在故障发生的第一时间先推一条urgent级公告,地图上立刻弹出"搜索暂时不可用、修复正在路上"的对话框——先安抚用户,再推真正的修复包。
边界与限制:这套机制不能做什么
诚实的边界同样写进了文档(Limits 一节):
- 真正的解析逻辑变更需要新代码。最多靠
transformsJs在沙箱里打搜索解析补丁(无 Java/反射/IO,2 秒超时强制终止),路线、自动补全等接口的重塑仍需发版; - 没有回滚:新包只会替换更低版本的包,撤销一次推送等于用更高版本号重新发布旧内容;
- 进程存活期间不更新:每个进程只拉取一次配置,长期挂着的进程要等下次启动才能看到新推送;
- 健康巡检哨兵:
.github/workflows/google-health.yml每天 14:20 UTC 用应用自己的请求构造器与解析器真实打 Google——读不懂就发邮件告警维护者。自愈机制之上,还有一道"提前发现漂移"的哨兵。
写在最后
Vela 的 calibration 机制给出了一个对普通应用也有借鉴价值的范式:把"容易腐坏的协议知识"从代码中剥离出来,用签名 + 主机白名单 + 版本号三道闸门保护远程配置通道,把接口漂移的修复周期从"应用商店发版"压缩到"一次 git 提交"。对 Vela 用户来说,这一切完全无感——你只是发现地图的照片、评论、热门时间始终好用,哪怕 Google 又悄悄改了页面结构。
更多细节可参阅 SPEC.md 第 3 节与 docs/book/07-talking-to-google.md。
【免费下载链接】Vela
Maps and turn-by-turn navigation for Android without Google Play Services: the best of open map data, with Google lookups by choice. Runs on degoogled phones and can avoid Flock cameras
相关推荐
如何看懂 Lithe 增量更新:Sparkle 签名、EdDSA 与自动回滚机制全揭秘
如何看懂 Lithe 增量更新:Sparkle 签名、EdDSA 与自动回滚机制全揭秘 Lithe 是一款面向 AI 时代的轻量级跨平台 IDE。它的 macO
开发工具代码编辑器AI 应用人工智能插件系统Aliucord Manager 签名机制揭秘:如何在设备上动态生成 Keystore 解决签名不匹配
Aliucord Manager 签名机制揭秘:如何在设备上动态生成 Keystore 解决签名不匹配 Aliucord Manager 是一款把 Discor
MTGA参数自愈机制揭秘:代理如何自动剔除上游不兼容的参数
MTGA参数自愈机制揭秘:代理如何自动剔除上游不兼容的参数 MTGA 是一款基于本地代理的方式,绕过 IDE 固定模型服务商限制的工具。当上游模型服务因为"不支
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考