yunzesms/docs/短信网关APK开发文档.md
2026-03-25 16:56:45 +08:00

249 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 短信网关 APK 开发文档
## 1. 文档目标
本文档用于指导开发一个 Android APK短信网关通过**自有手机号**实现短信验证码的接收、解析、转发,以及按需发送短信。
目标是不依赖第三方云短信服务,构建可自部署、可运维、可扩展的短信能力。
## 2. 适用场景
- 自有系统登录验证码收集与转发
- 小规模业务短信收发自动化
- 企业内网或私有化环境下的短信接入
> 注意:必须用于合法合规的业务场景,禁止用于批量注册、绕过风控、骚扰营销等违规用途。
## 3. 总体架构
### 3.1 架构组件
1. **Android 短信网关 App**
- 监听并接收短信
- 解析验证码或原始短信文本
- 调用后端 API 上报短信
- 接收后端任务并发送短信
2. **后端服务(自建)**
- 接收网关回调
- 下发发送任务
- 记录日志、重试、告警
- 提供业务系统查询接口
3. **业务系统**
- 发起发送请求
- 获取验证码处理结果
### 3.2 数据流
1. 上游平台向手机号发送验证码短信
2. Android 网关接收到短信广播
3. 网关解析短信内容(提取验证码)
4. 网关将完整短信 + 解析结果上报后端
5. 业务系统从后端查询验证码并完成流程
发送流程(可选):
1. 业务系统调用后端发短信接口
2. 后端生成发送任务
3. 网关轮询/长连接获取任务
4. 网关使用 `SmsManager` 发送短信并回执结果
## 4. 技术选型建议
- **客户端**Android 原生 Kotlin推荐
- **网络层**Retrofit + OkHttp
- **本地存储**Room 或轻量 SQLite
- **日志**:本地文件 + 后端集中日志
- **心跳与保活**Foreground Service + WorkManager
> 若主项目使用 uniapp建议通过原生插件封装短信能力不建议纯前端层直接处理短信底层功能。
## 5. Android 权限与系统能力
## 5.1 必要权限
`AndroidManifest.xml` 中声明:
- `android.permission.RECEIVE_SMS`
- `android.permission.READ_SMS`(如需读取短信内容库)
- `android.permission.SEND_SMS`
- `android.permission.RECEIVE_BOOT_COMPLETED`
- `android.permission.FOREGROUND_SERVICE`
运行时动态申请:
- `RECEIVE_SMS`
- `READ_SMS`
- `SEND_SMS`
## 5.2 广播接收
核心广播:
- `android.provider.Telephony.SMS_RECEIVED`
实现方式:
- 注册 `BroadcastReceiver`
- 从 PDU 解析短信发送方、内容、时间戳
- 在接收器中快速落库与入队,避免阻塞主线程
## 5.3 发送短信
使用 `SmsManager`
- 单卡:`SmsManager.getDefault()`
- 双卡:按 `SubscriptionId` 获取目标 `SmsManager`,避免走错 SIM 卡
## 5.4 保活策略
- 前台服务常驻(通知栏提示)
- 开机自启恢复服务
- 引导用户关闭电池优化限制
- 关键任务使用 WorkManager 重试
## 6. 模块设计
## 6.1 模块划分
1. **sms-receiver**:短信接收与解析
2. **sms-sender**:短信发送与发送回执
3. **task-sync**:任务拉取、心跳、状态上报
4. **storage**:本地缓存与失败队列
5. **api-client**:后端 API 通信
6. **security**:签名、鉴权、加密
## 6.2 关键数据结构(建议)
### InboundSms入站短信
- `id`
- `sender`
- `content`
- `receivedAt`
- `simSlot`
- `parsedCode`
- `parseStatus`
- `uploadStatus`
- `rawPduHash`
### OutboundTask出站任务
- `taskId`
- `phone`
- `content`
- `simSlot`
- `status`pending/sending/success/failed
- `retryCount`
- `lastError`
## 7. 后端接口设计(示例)
## 7.1 鉴权建议
- 每台设备分配 `deviceId + deviceSecret`
- 请求头携带签名HMAC-SHA256
- 使用 HTTPS拒绝明文传输
## 7.2 API 列表
1. `POST /api/v1/sms/inbound`
- 作用:上报入站短信
- 请求体发送方、短信内容、时间、设备ID、解析结果
- 返回:`ackId`
2. `GET /api/v1/device/tasks?deviceId=xxx`
- 作用:拉取发送任务
- 返回:任务列表
3. `POST /api/v1/sms/outbound/result`
- 作用:回传发送结果
- 请求体:`taskId`、状态、失败原因、运营商回执(如有)
4. `POST /api/v1/device/heartbeat`
- 作用:设备在线心跳
- 上报电量、网络、SIM状态、App版本
## 8. 验证码解析策略
## 8.1 正则提取建议
建议预置多个规则,按顺序匹配:
- `\\b\\d{4}\\b`
- `\\b\\d{6}\\b`
- `验证码[:\\s]*([0-9]{4,8})`
## 8.2 容错策略
- 同一发送方短时间多条短信,按时间窗口聚合
- 对重复短信做哈希去重
- 解析失败也要上报原文,便于后端二次识别
## 9. 异常与重试机制
- 网络失败:指数退避重试(如 2s/5s/10s/30s
- 接口 5xx自动重试
- 接口 4xx记录并告警不无限重试
- 本地持久化失败队列,避免进程被杀导致数据丢失
## 10. 安全与合规要求
- 严格控制设备与接口访问白名单
- 本地敏感数据最小化存储,必要时加密
- 日志脱敏(手机号中间位、验证码字段)
- 定期轮换设备密钥
- 仅用于已授权业务,不得违反运营商与法律规定
## 11. 测试计划
## 11.1 功能测试
- 接收短信:不同发送方、长短信、分片短信
- 发送短信:单卡/双卡、不同运营商号段
- 解析测试4位/6位/8位验证码、多语言模板
- 任务链路:拉取、执行、回执、重试
## 11.2 稳定性测试
- 24小时持续运行
- 断网恢复
- 杀进程后自恢复
- 低电量模式、系统省电模式下行为
## 11.3 压力测试
- 高频短信接收场景
- 并发任务发送场景
- 后端不可用情况下队列堆积与恢复
## 12. 发布与运维建议
- 渠道企业内部分发、MDM、私有下载页
- 不建议直接面向公开应用市场发布
- 建立设备监控面板:在线率、延迟、失败率
- 预留远程配置开关:正则规则、重试参数、限流阈值
## 13. 里程碑计划(建议)
1. **M11周**:完成收短信 + 上报 API
2. **M21周**:完成发短信任务闭环
3. **M31周**:完成保活、重试、日志
4. **M41周**:完成灰度部署与稳定性压测
## 14. 最小可用版本MVP范围
- 接收短信并解析验证码
- 上报后端并可查询
- 支持基础发送任务
- 支持失败重试与本地缓存
- 提供基础运行状态页(在线、最近短信、错误信息)
---
如需继续推进,可在下一步补充:
1. Android 端包结构与类图
2. 完整 `AndroidManifest.xml` 示例
3. Kotlin 核心代码模板Receiver/Service/SmsManager/API
4. 后端接口 OpenAPI 文档草案