feat(android): 安卓端增加摇一摇自动记账功能#321
Conversation
| @@ -1,10 +1,10 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_riverpod/flutter_riverpod.dart'; | |||
| import 'package:url_launcher/url_launcher.dart'; | |||
| import '../../providers.dart'; | |||
| /// 默认模板。强制 JSON 数组 + 完整字段说明 + 多笔示例。 | ||
| /// 默认模板。先判断是否为账单,再强制 JSON 数组 + 完整字段说明 + 多笔示例。 | ||
| static const String defaultTemplate = | ||
| '''{{INPUT_SOURCE}}提取记账信息,返回JSON数组。 |
|
@wait-more 思路我认为没问题,但是一直不做无障碍的原因是不符合无障碍这个功能的本意+会被拒审。所以这里要区分环境,google play这种场景肯定是无法过审的。 另外当前pr夹杂了一些不相关的内容,建议分批次提pr,目前的review难度有点大。 |
| @@ -0,0 +1,615 @@ | |||
| # 摇一摇自动记账方案 | |||
|
|
|||
好的,我先拆分和简化一下 |
038b888 to
f4fc7d2
Compare
- 摇一摇检测:ShakeDetector 加速度传感器,连续峰值算法判定摇动动作 - 无障碍截屏:BillingAccessibilityService 接管截屏,API 31+ 截屏文件 / API 30- 节点文本双路径 - 五层保活:前台服务+通知栏+JobScheduler+广播唤醒+相互唤醒 - 设置页:无障碍引导、保活状态/电池优化/自启动检查、通知渠道横幅检测 - 启动恢复:应用重启后自动恢复摇一摇与保活状态 - 通知优化:processScreenshot 支持 showProgressNotifications 参数控制中间通知; 结果通知优先走原生通道,降级 Flutter 通知 + SP 兜底; 超时后等待 AI 延迟响应,通知追加待处理计数
f4fc7d2 to
3e6bdb7
Compare
|
@TNT-Likely 作者大佬,最新的提交已完成功能拆分和代码精简,当前剩的基本都是和摇一摇自动记账功能相关的代码了,你看下呢 |
|
首先认真说一句:这个 PR 的工程投入和完成度都看得出来——ShakeDetector 的峰值节律抗误触、顺序处理队列、原生超时兜底、Engine 死活检测,这些设计都有想法,文档注释也很扎实。正因为如此,更要把结论和理由完整地写清楚。 结论:这个方向我们在 2026-05-30 和 06-04 做过两轮专门评审,最终搁置了,这个 PR 暂时不能合入主干。 决定性原因不在代码,在平台:
PR 目前没有任何渠道门控,功能会进所有 build 包括 Play 包。如果未来要做这个功能,前提是接受「国内渠道 flavor 独占 + Play 包完全剥离无障碍服务声明」的双 build 方案——这是产品层面的决策,不是代码改一改能绕过的。 —— 除平台问题外,几个架构/正确性问题也记录在这里,部分对你后续拆分 PR 有用: 双 FlutterEngine 跑同一个
正确性问题
对既有功能的外溢
流程
—— 可以继续的方向:
再次感谢投入,这不是对工作量的否定,是平台把这条路焊死了——希望上面的技术记录对后续拆分有帮助。 |
|
@wait-more 补充一下上面说的「渠道门控」具体怎么做——项目里已经有现成机制(截屏自动记账就是这样在 Play 版被剥离的),照着接即可: 项目现状:同一个 tag,CI 构建两种产物(
三层门控,从外到内: 1. Dart 层 — 编译期常量(参考 const _isGooglePlayBuild = bool.fromEnvironment('GOOGLE_PLAY', defaultValue: false);
因为是 2. 原生 Manifest 层 — 构建时 overlay 剥离(无障碍场景的关键一层) 光 Dart 门控不够:manifest 里只要存在 <service android:name=".BillingAccessibilityService" tools:node="remove" />
<service android:name=".KeepAliveService" tools:node="remove" />
<service android:name=".KeepAliveJobService" tools:node="remove" />
<receiver android:name=".BootReceiver" tools:node="remove" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" tools:node="remove" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" tools:node="remove" />Kotlin 类本身可以留在包里(没有 manifest 声明系统就不会绑定它),但权限和四大组件声明必须从 Play 包的 merged manifest 里消失。构建完 CI 会 3. 体验层 — 运行时兜底提示 APK 渠道用户从 Play 重装/迁移过来时设置项会"消失",开关页最好放一行说明(如"此功能仅 GitHub 直装版提供"),避免被当成 bug 反馈。 验证方式:构建 AAB 后用 —— 即使做了以上门控,Android 16/17 的 OS 级吊销问题对 APK 渠道用户依然存在(高级保护模式下系统会自动关闭非辅助工具的无障碍授权),这是功能本身要在开启引导里向用户说明的限制。所以整体路径是:先开 issue 把双 build 方案 + 双引擎架构问题的解法确认下来,再动手改,避免再返工一轮。 |
变更类型
变更说明
当前安卓端缺少一种更无感或更自动化的记账方式。现有方案需手动截屏(电源键+音量键)触发相册监听,操作路径长且截图残留系统相册难以清理。某些品牌ROM甚至需要截图后马上切入app,app才能识别到新截图再触发流程,极大影响用户体验。Android 缺少 iOS Shortcuts + Back Tap 这类系统级快捷记账能力,因此借助 AccessibilityService + 加速度传感器自建一条不依赖相册的独立通路。
本功能优势:
实现内容:
相关 Issue
无对应 issue。
测试情况
截图(如适用)
检查清单
dart format格式化代码flutter analyze无警告