安卓微信收款通知监听 App — 完整提示词
# 角色定义
你是一位资深安卓开发工程师,精通 Kotlin、Android NotificationListenerService、网络通信和后台服务开发。
请帮我开发一个安卓应用,功能是:监听手机通知栏中的微信收款通知,解析出收款金额和收款时间,将数据 POST 到用户指定的 URL,用于远程统计收款数据。
# 一、核心功能需求
## 1. 通知监听
- 使用 `NotificationListenerService` 监听系统通知栏
- 只处理来自微信(包名 `com.tencent.mm`)的通知
- 根据用户自定义的关键词列表匹配通知内容,只有命中关键词的通知才进行解析(例如"收款"、"微信支付"、"到账"等)
- 未命中关键词的通知直接忽略,不做任何处理
## 2. 通知解析
- 从通知的 `title` 和 `text` / `bigText` 中提取以下字段:
- **收款金额**:正则匹配人民币金额,支持"¥"、"¥"、"元"等格式,例如 `¥10.00`、`收款金额10.00元`、`10.00`
- **收款时间**:优先使用通知的 `postTime`(系统级时间戳,最准确);如通知文本中包含具体时间也可作为备选解析
- **付款方**(可选):尝试从通知文本中提取付款方昵称,提取不到则留空
- **通知原文**:保留原始通知文本,用于调试和排查
- 解析失败时记录日志,不发送数据,不崩溃
## 3. 数据上报
- 将解析结果以 JSON 格式 POST 到用户配置的 URL
- 请求体格式示例:
```json
{
"amount": "10.00",
"time": "2025-01-15T14:30:00",
"payer": "张三",
"rawText": "微信支付收款¥10.00",
"appName": "微信",
"deviceId": "用户自定义设备标识",
"timestamp": 1736932200000
}
使用 OkHttp 发送请求,设置合理的超时时间(连接 10s,读取 15s)
请求失败时本地缓存(使用 Room 或轻量 JSON 文件),待网络恢复后重试上报
支持配置请求头(如自定义 Authorization Token)
4. 去重机制
对同一通知避免重复上报:以通知的 postTime + amount + rawText 的 hash 作为唯一标识
已上报的标识缓存最近 500 条(LRU),命中则跳过
二、自定义配置项(应用内设置页面)
用户可在 App 内设置以下配置,使用 SharedPreferences 或 DataStore 持久化:
配置项 说明 默认值
上报 URL 接收 POST 请求的服务器地址 空(必填)
关键词列表 匹配通知的关键词,逗号分隔,支持多个 收款,微信支付,到账
设备标识 用于服务端区分不同设备 空(建议填写)
请求头 Token 附加到请求头的认证令牌(可选) 空
开关:监听启用 总开关,控制是否开始监听 false
开关:调试日志 是否在设置页显示最近的通知解析记录 false
自定义应用名称 显示在桌面和通知中的应用名 收款助手
三、权限清单与说明
必需权限(AndroidManifest.xml)
<!-- 通知监听服务权限(系统级,用户需在设置中手动授权) -->
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" />
<!-- 网络通信 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 前台服务(Android 9+ 后台保活必需) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- Android 14 (API 34) 需声明前台服务子类型 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<!-- 开机自启(可选) -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- 请求忽略电池优化(可选,提升后台存活率) -->
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
权限说明
BIND_NOTIFICATION_LISTENER_SERVICE:核心权限。无法通过代码直接授予,必须引导用户前往 设置 → 通知访问权限 手动开启。App 首次启动时应检测此权限状态,若未授权则显示引导页面,提供跳转按钮。
POST_NOTIFICATIONS(Android 13+ / API 33+):本 App 自身不需要发通知(前台服务通知除外),前台服务通知在 Android 13+ 需要此权限,需运行时申请。
FOREGROUND_SERVICE_SPECIAL_USE:Android 14 要求所有前台服务声明子类型。本 App 使用 specialUse 类型,并在 Manifest 的 <service> 标签中通过 <property> 声明用途说明。
四、Android 版本兼容性
目标与最低版本
compileSdk = 35(Android 15,最新)
targetSdk = 35
minSdk = 26(Android 8.0,覆盖 95%+ 设备)
各版本适配要点
Android 版本 API 适配要点
8.0 (26) 26 后台服务限制:必须使用前台服务,startForegroundService()
9.0 (28) 28 前台服务需调用 startForeground() 在 5 秒内
12 (31) 31 前台服务启动限制:从后台启动前台服务受限,需豁免或使用 WorkManager 拉起
13 (33) 33 POST_NOTIFICATIONS 运行时权限;通知监听权限的引导文案更新
14 (34) 34 前台服务必须声明 foregroundServiceType;通知监听 Service 需指定类型为 specialUse
15 (35) 35 16KB 页面大小支持(在 gradle 中配置 android.useAndroidX=true 和相关适配);前台服务行为进一步收紧
NotificationListenerService 的版本注意
Android 4.3 (API 18) 起支持,本 App minSdk 26 无兼容问题
onNotificationPosted() 回调在主线程,网络请求必须切到子线程(使用协程 Dispatchers.IO)
部分厂商 ROM(小米/华为/OPPO/vivo)可能限制通知监听 Service 的后台运行,需引导用户关闭"省电策略"或加入"自启动白名单"
五、微信通知格式适配
微信包名
正版微信:com.tencent.mm
分身/双开微信:包名不确定,可在设置中让用户自定义监听包名列表(高级选项)
收款通知常见格式(基于微信 8.x 版本)
微信收款到账时,通知栏通知的 title 和 text 通常为以下几种格式之一:
格式1(个人收款码):
title: "微信支付"
text: "收款金额¥10.00" 或 "微信支付收款10.00元"
格式2(商户收款):
title: "微信支付"
text: "顾客支付¥10.00" 或 "今日累计收款¥xxx"
格式3(转账收款):
title: "微信"
text: "张三给你转账¥10.00"
格式4(新版微信 8.0.40+):
title: "微信支付"
text: "收款到账¥10.00"
bigText: "收款到账¥10.00\n付款方:张三\n备注:xxx"
解析策略
金额正则:[¥¥]?\s*(\d+(?:\.\d{1,2})?)\s*元?,取第一个匹配组
关键词匹配:对 title + text + bigText 拼接后的全文做关键词包含判断
付款方提取:正则 付款方[::]\s*(.+) 或 (.+)给你转账
上述正则和格式仅为参考基准,实际应以真机抓取的通知为准。请在代码中做好"解析不到不崩溃"的防御性编程
微信版本说明
当前微信最新正式版约为 8.0.5x(2025年),通知格式可能随版本调整
App 不依赖微信的任何 API 或无障碍服务,仅通过通知栏文本解析,不涉及微信逆向
如微信未来通知格式变化导致解析失败,用户可通过"调试日志"功能查看原始通知文本,手动更新关键词和正则
六、UI 设计
页面结构(最简)
1. 主页面 / 状态页
App 名称(用户自定义)
监听状态指示灯(绿色=运行中,红色=已停止)
通知监听权限状态 + "去授权"按钮
今日收款笔数 / 今日收款总额(本地统计展示)
最近一笔收款记录(金额 + 时间)
底部 Tab:状态 | 设置 | 日志
2. 设置页
上报 URL 输入框
关键词输入框(逗号分隔)
设备标识输入框
请求头 Token 输入框
监听总开关
调试日志开关
高级选项(折叠):自定义监听包名、金额正则自定义、去重缓存大小
"测试上报"按钮:发送一条测试数据到配置的 URL,验证连通性
"导出日志"按钮
3. 日志页(调试用)
时间倒序列表显示最近的通知解析记录
每条记录显示:时间、原标题、原文本、解析结果、上报状态
支持清空日志
UI 技术栈
使用 Jetpack Compose 构建 UI(Material 3)
深色模式支持
最简设计,不需要花哨的动画
七、技术栈与项目配置
语言与框架
Kotlin(最新稳定版)
Jetpack Compose + Material 3
MVVM 架构 + ViewModel + StateFlow
OkHttp 用于网络请求
Moshi 或 Gson 用于 JSON 序列化
DataStore (Preferences) 用于配置持久化
Room 用于上报缓存和日志存储(可选,轻量方案可用 JSON 文件)
Gradle 配置要点
applicationId:使用占位符,构建时可自定义替换(例如 com.example.paymentmonitor),在 build.gradle.kts 中通过 project.findProperty("customApplicationId") 读取,支持命令行传入
namespace 与 applicationId 一致
版本号:versionCode = 1, versionName = "1.0.0"
启用 ViewBinding 无需(使用 Compose)
buildFeatures { compose = true }
项目结构
app/src/main/
├── java/com/example/paymentmonitor/
│ ├── MainActivity.kt // 入口,Compose 导航
│ ├── service/
│ │ └── PaymentNotificationListener.kt // NotificationListenerService 实现
│ ├── data/
│ │ ├── ConfigManager.kt // 配置读写
│ │ ├── NotificationParser.kt // 通知解析逻辑
│ │ ├── ReportClient.kt // HTTP 上报
│ │ └── DedupCache.kt // 去重缓存
│ ├── ui/
│ │ ├── StatusScreen.kt
│ │ ├── SettingsScreen.kt
│ │ └── LogScreen.kt
│ └── model/
│ └── PaymentRecord.kt // 数据模型
├── res/
└── AndroidManifest.xml
八、前台服务与保活
NotificationListenerService 被 system_server 绑定,本身具备一定的系统级保活能力,优于普通后台服务
但部分国产 ROM 仍可能杀掉,需额外措施:
将 NotificationListenerService 同时注册为前台服务(Android 14 需 foregroundServiceType="specialUse")
前台服务通知设置为低优先级、无声音、不可取消,最小化对用户的打扰
引导用户在系统设置中关闭对该 App 的电池优化
可选:注册 BOOT_COMPLETED 广播接收器,开机后检查配置并提示用户确认监听权限
九、安全性考虑
上报 URL 支持 HTTPS,App 内对 HTTP 做警告提示(不阻止但提示风险)
请求头 Token 存储在 DataStore 中,不上传到日志
日志中的通知原文可选择脱敏(隐藏付款方姓名的中间字符)
App 不请求任何与功能无关的权限
不收集任何不必要的数据,不上报到除用户配置 URL 外的任何地址
ProGuard/R8 混淆启用
十、构建与自定义
自定义 Application ID
在 gradle.properties 或命令行中传入:
./gradlew assembleDebug -PcustomApplicationId=com.yourcompany.paymonitor
build.gradle.kts 中:
android {
defaultConfig {
applicationId = project.findProperty("customApplicationId")?.toString()
?: "com.example.paymentmonitor"
}
}
自定义应用名称
通过 res/values/strings.xml 中 app_name 配置,或运行时通过 ActivityManager.setApplicationLabel()(有限支持)。建议构建时通过 resValue 注入:
defaultConfig {
resValue("string", "app_name", project.findProperty("customAppName")?.toString() ?: "收款助手")
}
十一、测试要求
提供 PaymentNotificationParser 的单元测试,覆盖上述 4 种微信通知格式 + 异常格式
提供去重逻辑的单元测试
提供配置读写的单元测试
在真机上验证:微信收款 → 通知触发 → 解析 → 上报 → 服务端收到数据的完整链路
十二、交付物
完整可编译的 Android Studio 项目源码
README.md:包含构建说明、自定义 Application ID 方法、权限授权引导步骤、各厂商 ROM 自启动设置指引
一份 sample-server.py:简单的 Python Flask 测试服务器,用于接收和打印上报数据,方便本地联调
---
## 提示词设计说明
| 设计点 | 为什么这样写 |
|--------|-------------|
| **权限逐条列出 + 说明** | 通知监听权限是系统级权限,用户必须手动授权,这是最容易卡住的地方 |
| **Android 版本适配表** | Android 14 的前台服务类型变更和 Android 13 的通知权限变更是两个硬门槛,不处理会直接崩溃 |
| **微信通知格式给 4 种示例** | 微信通知格式随版本变化,给 AI 多个样本让它写更健壮的正则,而不是只写一种然后漏掉其他 |
| **自定义 applicationId 用 gradle property** | 你提到要自定义应用 ID,用 `-P` 参数传入是最干净的方式,不污染代码 |
| **关键词做成用户可配置** | 你提到自定义关键词,放在设置页让用户自己改,比硬编码灵活得多 |
| **去重机制** | 通知可能重复触发(用户滑动通知栏等),不做去重会导致重复上报 |
| **失败缓存重试** | 手机网络不稳定,丢数据就丢钱了,必须缓存重试 |
| **国产 ROM 保活说明** | 小米/华为/OPPO/vivo 都会杀后台,这是实际部署中最大的坑,提示词里明确提了 |
| **sample-server.py** | 交付一个测试服务器,你拿到代码后能立刻本地验证闭环,不用先搭服务端 |
- 点赞
- 收藏
- 关注作者
评论(0)