用AI做APP逆向不难:硅基轻享App 蓝牙断连修复
8 月 10 日早上,我把手机的系统日志和电池历史重新对了一遍。
前一晚 23 点 38 分,硅基轻享 App 已经连上探头。手机随后灭屏,这条 BLE 链路在后台稳稳跑了 6 小时 57 分。直到早上 6 点 35 分 54 秒,系统报错,大概意思意思是连接超时,链路数据丢了。
App 当场发起第 0 次重连,没找到。约 70 秒后又试一次,还是没找到。6 点 39 分,它终于扫到探头,1 秒后 GATT 连接成功,3 秒后认证完成,血糖数据继续接收。
可这还没完。大约 79 秒后,连接又掉了一次。App 在 6 点 41 分 03 秒重新找到探头,信号更弱,-83 dBm。前几次连接撞上常见的 status=133,它没有卡死。6 点 41 分 12 秒再次连上,2 秒后通过认证,数据恢复。
最关键的问题:这两次重连到底是不是我亮屏以后才发生的?
不是!!
手机从 6 点 35 分一直灭屏到 6 点 45 分。两次 GATT 连接发生在 6 点 39 分和 6 点 41 分,完整落在灭屏区间里。App 进程始终是同一个 PID,BLE 前台服务和近距离设备服务也一直在。
到这里,我可以把结论写出来了!
硅基轻享 v16.1-hf5 已经在 Android 16 的三星真机上,完成了有系统日志、血糖数据记录互相印证的灭屏后自动重连
为了拿到这几行结论,我和 Codex 从 v16 做到 v16.1,又经历 hf2、hf3、hf4,最后才到 hf5。中间短信登录闪退过,密码登录后崩过,自动连接和手动连接也曾一起失效。换到另一台手机覆盖安装时,还冒出一个看似像蓝牙问题、实际藏在探头算法里的崩溃。
整个过程挺折腾的,新的问题一直出现,AI如此强大,但也远没有「让 AI 改个 App」听上去那么轻巧。
(已将本项目开源在我的github,最终的apk文件可以实现硅基轻享App的血糖数据发送、蓝牙断连后自动重连,但考虑到一些风险,codex建议我只将我修改的部分放出来。大家也可以将本文喂给ai,让它修改)
1、血糖数据断连
我戴着硅基轻享探头,只要离手机远一点,蓝牙就会断。这正常的,BLE 有距离限制,中间隔几堵墙或者人体遮挡,信号就掉下去了。
最烦的是回来以后。
几秒钟的短时间离开,连接通常能恢复。离个几分钟,等我发现数据不对时可能已经过去几个小时。

打开硅基轻享 App,连接页面先转几秒,有时十几秒,然后才重新连上。
当时我最怀疑的是,App 平时并没有持续恢复连接。亮屏或者打开页面以后,我的某个动作才把连接流程重新推起来。
还有一件事:手机没有休眠这个 App。 硅基轻享在电池白名单里,后台权限正常,前台服务也在。后来 Codex 读取系统状态,也证实了:进程活着,服务活着,蓝牙扫描和连接权限都没有被关掉。
我的要求后来被一点点写清楚了。人离开范围,连接可以断。回到范围,App 要自己继续尝试连接探头。亮屏能连,灭屏也得能连。 扫描或连接卡住,不能永远停在一个假重新连接状态。修改也不能碰 App 现有的血糖算法、探头协议、账号数据。
这毕竟不是一个音乐播放器。我可以接受弱信号下多等一会儿,不能接受它悄悄停掉几个小时,界面还只显示一个不停转的圆圈。
2、我先让 Codex 读 APK安装包
这个项目没有一套可以直接打开编译的完整源码,手里主要是 APK 和之前整理的版本。
我的第一条要求。
详细分析 APK 中现存的 BLE 重连机制。
不要修改 App,也不要修改手机。
把断开、扫描、连接、重试和停止条件串起来。
先输出一份增量修复设计文档。
这一步起步慢,其实反过来看省了最多的时间。

Codex 反编译 硅基轻享app v15版本后,沿着回调、Handler 和 BLE SDK 把流程还原出来。设备断开时,LocalBleService 会投递一条重连消息。亮屏时大约等 1.5 秒,锁屏时固定等 5 分钟。消息执行后,SDK 扫描约 60 秒,找到目标便进入 GATT。没找到,就等回调安排下一轮。

乍看之下,App 明明有重连。继续往里读,才发现毛病。
一个扫描错误分支会先调用停止方法,把内部状态设成「用户已停止」,随后又安排重试。等 Handler 真正执行,它检查的恰好是「用户没有停止」。 程序一边预约下一轮,一边把门从里面锁上了。
SDK 的另一个断开分支也会自我阻断。
连接入口还会返回忙碌、已有目标等状态码,原来的上层基本没处理。扫描和连接也缺少外层超时。如果底层回调没有按预期回来,App 会一直认为任务还在进行。
另一个坑藏在「已连接」后面。底层刚报 GATT 连接成功,旧逻辑就取消重连消息,可服务发现、通知订阅和第一条有效数据都还没完成。遇上假连接或残留状态,后手已经先撤了。
至于为什么打开页面后常常又能连上,代码里也能解释。连接页面会重新调用连接入口,有机会绕过已经失效的 Handler,顺便清理旧状态。
读到这里,我和 Codex 才知道真正要补的是什么。
要给连接流程加一个能长期盯着状态的玩意。
3、解决灭屏扫描连接
我让 Codex 新建 v16 文件夹,v15 保持不动。手机上的 App 也先不碰。每个 APK 必须在 MuMu 模拟器跑过,我再决定要不要上真机。
v16 修的第一件事,是那个自相矛盾的停止标记。扫描失败以后,重试终于能真的执行。连接返回码也开始由上层处理,不再调用完就当没事。
重试间隔改成有上限的退避,从 1.5 秒、5 秒逐步增加到 120 秒,失败后不会无限制扫描。
扫描或连接长时间没有进展,外层看门狗会做一次受控软重置。它带冷却时间,短时间内不会反复折腾。App 还会检查最近有没有收到有效数据,没有的话,也要重新审视整条链路。
BLE 服务改成可由系统恢复的启动方式。Codex 还加了一份很小的本地环形日志,只记录时间、状态和失败原因,不写血糖值、账号、令牌、完整设备名或 MAC。
协议、服务 UUID、认证和数据库都没改。我最初也明确要求不碰血糖算法。后来 hf5 之所以不得不修算法相关类,是因为真机已经证明旧 APK 里的类本身会崩,这件事后面再说。
v16 在 MuMu 上通过以后,我允许它覆盖安装到手机。
很快又看到一个奇怪现象。灭屏期间扫描已经启动,系统统计里的结果却一直是零。屏幕一亮,几秒内突然进来几十个广播,随后 GATT 连上,数据恢复。有一次甚至还没真正打开 App,连接就已经回来。
这下问题。。。变了。。。
起作用的可能不是点击 App,而是亮屏本身。
Codex 回头检查扫描参数,又核对了 Android 的 [BluetoothLeScanner 文档]和[后台 BLE 指南]。Android 会在熄屏后暂停无过滤扫描。想让结果继续送到 App,需要交给系统一个有效的 ScanFilter。
原 SDK 确实建了过滤器对象,只是设备名、地址和服务 UUID 全为空。对 Android 来说,这依旧是无过滤扫描。
v16 把「重试会死」救活了,却没让灭屏扫描真正收到广播。这才有了 v16.1。
第一次改 v16.1 时,Codex 用 SDK 保存的探头名做过滤。这里又踩了个坑。SDK 只保存广播名末 4 位,过去的做法是先接收广播,再在 App 里比对后缀。Android 的 ScanFilter.setDeviceName() 却要求完整设备名精确匹配,不支持后缀。
真实设备名有 10 个字符,过滤器手里只有 4 个。结果可想而知。
当时从界面看,App 忙得很,每隔一阵就启动扫描,系统注册扫描器也总是成功。真实结果始终是 0。手动点击连接也没用,因为手动和自动走的是同一个入口。
hf4 最后采用了一个更稳的方法。亮屏继续使用原来的扫描路径,灭屏时交给 Android 三种非空条件,包括完整设备名、兼容短名称和探头服务 UUID。任意一种收到广播以后,还要再过 SDK 原有的绑定校验,不会因为放宽发现范围就随便连向别的设备。
这个版本在手机上跑出了文章最早的灭屏证据。灭屏 7 秒后断线,约 26 秒恢复。
那时我以为已经快结束了。
其实没有。后面又搞了2天!
4、同一个 APK文件,换台手机安装,为什么会闪退
后面的事情一度很玄学。
v16.1-hf4 在我的 S23u 上能跑,覆盖安装到另一台 S25u 后,却出现连接探头时闪退。

更奇怪的是,如果先卸载旧版,再全新安装 hf4,问题似乎又消失了。
我刚开始还在怀疑是不是手机问题。。。
可codex说日志不认这种模糊的解释。

S25u 当时的探头走的是 ALGORITHM E1.1.2G(2024_05_15)。进入这条路径以后,com.algorithm.e112g.AlgorithmContext.toString() 被 Android 16 判定为无效方法,因为它执行到结尾却没有返回指令。系统先抛 VerifyError,接着 JNI 触发 SIGABRT。
最后就是我看到的连接过程中突然退出,随后系统提示 App 屡次停止运行。
之前的 S23u 走的是另一套算法路径,所以同一个坏类一直躲着,没有被加载。
这也解释了为什么卸载后重装一度看起来正常。卸载会清掉本地绑定和旧状态,触发路径发生变化,坏代码可能暂时没有走到。
我每 14 天要换一支探头。下一支探头如果换了算法版本,难道还要再赌一次?
不能这么修。
我让 Codex 制作 hf5,一次检查 APK 里已经支持的四套算法。结果发现,其中三套 AlgorithmContext.toString() 都需要修复,分别是 V1.1.2E、E1.1.2G 和 E1.1.5M。E1.1.5N 原本正常,保留不动。

更让我在意的是旧算法工厂对未知版本的处理。它会悄悄回退到 E1.1.5M。对于普通功能,默认值偶尔能救场。放到血糖算法这里,猜错比报错更危险。
一个新的探头如果被塞进旧算法,没有数据都算好的,给出一个看起来很正常的错误数字那就完蛋了。
hf5 改成了拒绝猜测。四套已知版本会先做类加载、实例化和 toString() 预检,连 VerifyError 这类错误也会被接住。遇到未知版本、空字符串、null 或预检失败,工厂返回空对象,BLE 初始化停止。
5、Codex 怎么计划和实施,我又怎么给它划定边界
我对 Codex 只说一句「帮我修好」,估计干不出这种结果。
这类任务横跨 APK、Android 系统、蓝牙硬件和真实血糖数据,一句话全放出去,最后鬼知道它改了什么。
我的方法是把每一阶段的目标、动作写清楚。
先描述观察:
观察到的现象是,短时间离开后能恢复,中长时间离开后要亮屏等待几秒。
已经确认 App 不会被休眠,前台服务和后台权限正常。
请读取系统状态和日志验证。
接着只读分析。
请分析 APK 的断开回调、扫描、连接、停止标记和重试调度。
把确定的问题、暂时的推测和需要真机验证的项目分开。
先交付 Markdown 设计文档,不要修改 App。
确认方案后才允许做新版本。
旧版本作为只读基线,新建独立版本目录。
不覆盖旧文件,不清手机数据,不修改系统设置。
先完成模拟器测试,真机安装必须再次得到我的允许。
这几句限制帮了大忙。v15 没被改,v16 和 v16.1 各自有目录,hf2 到 hf5 也能追溯。每个最终包都有版本号和 SHA-256,手机里装的是哪一个,明明白白。
真机操作我也每次单独授权,Codex 做到边界时就停下来等我确认。
这里还有一个挺实用的经验。让 Codex 报「连接成功」时,不只看界面上的图标。我的验收链路是扫描发现目标、GATT 连接、服务发现、通知订阅、认证完成、新数据到达。前面任何一步停住,都不算恢复。
判断灭屏重连也一样。要把断线时间、扫描时间、GATT 时间、屏幕开关记录和进程状态放在一条时间线上。 这样才能分清是后台自己连回,还是亮屏以后才重新开始工作。
6、我做过的测试
MuMu 的价值:它先替真机拦坏包。
每次构建后,Codex 都会检查 DEX 能否重新汇编,APK 有没有完成 zipalign,v1、v2、v3 签名能不能通过,证书是否一致。之后从旧版覆盖安装,反复冷启动,切换短信登录和密码登录,再查 VerifyError、FATAL EXCEPTION、SIGABRT 和 ANR。
hf5 在 MuMu 上连续做了 5 次冷启动。四套已支持算法分别加载对应的 ARM 原生库,读取到完全匹配的原生算法版本,4 套全部通过。未知版本、空字符串和 null 也逐一试过,3 种情况都安全返回,没有闪退。
为了确认没有顺手改坏其他东西,Codex 把 hf5 和 hf4 的 APK 逐项比较。4290 个非签名条目里,新增 0,删除 0。只有 AndroidManifest.xml、classes.dex 和 classes5.dex 有变化,对应版本号、三套损坏类和算法工厂保护。
这些检查很有用,但 MuMu 没有连上我的的真实探头。它可以证明安装、启动和算法加载是ok的,但是证明不了隔着一堵墙还能不能收到广播,更证明不了灭屏几小时后会怎样。
所以最后一关只能是真机!!

最近这次过夜测试就还不错。23 点 38 分建立连接,灭屏后稳定运行近 7 小时。6 点 35 分第一次掉线,之后在灭屏状态下完成2次恢复。第一次重连时 RSSI 是 -82 dBm,第二次是 -83 dBm,中间还出现 status=133。
它说明信号差时仍可能反复失败,但重连状态机没有因为一次失败就死掉。
7、最后结果
目前能确认的结果有三个。
v16 修掉了重试流程会自我停止的问题。v16.1-hf4 让 Android 在灭屏时也能把探头广播交给 App。hf5 又补上四套已知探头算法的校验,并为未来未知算法加了拒绝计算的保护。
更重要的是,hf5 已经在我的三星手机上留下了两次灭屏重连记录。 App 和探头的蓝牙连接不是等屏幕亮起后才恢复,也不是巧合。日志里有同一进程、同一服务、明确的 GATT 时间和随后的数据接收。
我现在才敢说,普通灭屏状态下的自动重连已经实现!!!!
我不敢说它从此百分之百秒连。BLE 会受距离、遮挡、系统蓝牙栈和同一探头的连接竞争影响。-82 dBm、-83 dBm 这种弱信号下,失败几次再恢复很正常。
这次用 Codex 最有用的地方,是它帮我把生活里的说不清道不明的一些感觉和想法变成可以核对的措施和证据。
我一开始看到的是「好像总要亮屏才连得上」。后来能说出无过滤扫描在灭屏后收不到结果。再后来能指出短设备名和系统精确过滤不匹配。到 hf5,又从「换手机就闪退」追到不同探头触发了不同算法类。
这不是一条神奇提示词换来的结果。更像两个人一起排障,我负责讲清现实里发生了什么,守住不能动的边界,决定什么时候让新包上手机。Codex 负责读 APK、日志和系统状态,做隔离版本,做改进,再用下一次测试推翻或者确认上一轮判断。
反正我这次最大的体会是,AI 写代码不难,难的是让它和我们一起尊重证据。
尤其当这份代码连着关系到身体的健康数据时。
安全说明
v16.1-hf5 是根据我自己的设备、原 APK 和使用环境制作的本地修改版,并非厂商官方版本。本文记录的是软件排障过程,不提供医疗建议。
如果觉得不错,随手来个三连吧,如果想第一时间看到我的文章,可以给个星标⭐~谢谢你看我的文章,我们下次见~
夜雨聆风