☰
Android短信来电自动转发方案:自部署规则过滤与多通道推送
2026/10/14 23:55:23 网站建设 项目流程

1. 人在外地,验证码和电话却留在了家里

这两年我做的最多的一件事,就是把一台旧安卓手机插上副卡扔在家里。这么做不是闲得发慌,纯粹是因为外出时收不到验证码实在太痛了。银行、账号登录、快递柜,每一处都卡在"短信验证码"这一步,而手机偏偏不在手边。等到晚上回酒店一看,屏幕上躺着十几条未读短信,其中一半是带时效的验证码,早过期了。来电也一样,快递员打了两通没接,第二天的派送直接被系统改成了"联系不上,退回"。

后来我开始琢磨一套短信转发加来电转发的方案,目标是让这台留守手机收到的验证码短信和重要来电,第一时间推到我现在能看到的设备上。调研了一圈现成方案,要么依赖某个云服务,消息要绕一圈别人的服务器,心里总觉得别扭;要么功能绑得死,没法按自己的规则过滤,营销短信和骚扰电话也会一股脑推过来,反而更吵。于是我自己动手做了一套,前后调了几个月,最后整理成一个开源项目,内部代号叫 RelayKit。

这套方案的核心思路并不复杂:手机端只负责接收,收短信、看来电,再把消息按配置的规则过滤一遍,然后通过设定好的通道往外推;通道层负责把消息送到人面前,我同时实现了HTTP回调、即时通讯机器人、邮件三种方式。整套东西自部署在自己设备上,不经过第三方消息平台,隐私和速度都更可控。适合的人也比较明确:有一定折腾能力的技术爱好者、经常出差且有双卡需求的用户,以及手里正好有一台闲置安卓机的人。

2. 短信靠广播、来电靠监听:两类转发完全不同的技术路径

短信和来电看着都是"接收通知",但底层机制完全不同,这直接决定了它们在系统里怎么触发、怎么拿数据、怎么处理特殊情况。如果只把它当成一个简单的通知转发器去做,后面大概率要反复返工。

2.1 短信转发的核心原理:系统广播与无序广播的截获时机

在Android里,新短信到达时系统会发送一条广播通知,应用只要提前注册了对应的广播接收器,就能收到这条广播,内容里带着发件人号码和消息正文。这条广播在Android 4.4版本之后有一个重要限制:如果应用不是系统默认短信应用,就无法读取短信内容,只能感知到"来了一条短信"。所以想真正转发内容,要么在设置里把应用设为默认短信应用,要么用较高优先级的接收器在别的应用之前抢先处理广播。

我实际采用的方式是注册高优先级接收器,在广播链路上比较靠前的位置读取消息,拿到内容之后立刻交给转发模块,同时不做任何拦截,让系统短信应用还能正常保存消息。这样做的好处是手机本身的信息流不受影响,来短信照样在短信App里能看到,转发只是"多看一眼"。代码层面就是声明权限、注册接收器、实现回调三个步骤,难点不在API本身,而在不同Android版本上广播行为的差异。比如部分系统里,普通静态注册的广播接收器在应用进程被杀后不会重新唤醒进程,必须配合前台服务才能保证消息到达时一定有机会处理。

2.2 来电转发的实现:电话状态监听与号码读取

来电转发没有现成的广播可以截获,需要走电话状态监听。系统会在手机的通话状态发生变化时回调应用注册的监听器,从"空闲"变为"响铃"的瞬间,可以拿到来电号码。这条路径的坑在于,号码的获取不是所有场景都稳定,部分运营商的VoLTE来电、隐藏号码显示等情况下,拿到的可能是null或者一个带特殊前缀的字符串,这些脏数据必须在转发前清洗掉。

实际处理的时候,我会先判断当前状态是不是真的切到了"响铃",避免把正在播出的电话误判成来电;然后对号码做一次归一化处理——去掉前缀空格、把国际号码格式转成本地格式,再交给规则引擎判断要不要推送。要让来电监听稳定运行,还需要在应用存活期间持续持有监听器引用,并且处理好电话状态回调的线程切换问题,回调不一定都发生在主线程上,涉及界面更新时尤其要注意。另外一个细节是,部分双卡机型需要分别监听两个卡槽的通话状态,否则另一张卡来电时可能完全感知不到。

2.3 为什么不碰无障碍服务

网上有不少"自动化转发"的教程走的是无障碍服务路线,也就是模拟用户在界面上读短信、跳转窗口。这套路子的糟心事我用过之后深有体会:效率低、系统兼容性差、稍微大型的版本更新就可能挂,而且很多应用商店对无障碍权限的审核越来越严,一个辅助功能权限申请不好解释清楚用途。更麻烦的是,无障碍服务需要保持常驻,系统对这类服务的限制也不少,省电策略一开,照样被杀。

相比之下,广播接收器和电话状态监听是系统开放给普通应用的常规能力,权限清晰、行为透明,也没有被特殊对待的风险。项目选型的时候我在这两条路上做过对比,最终还是选了后者,虽然拿到的信息没有无障碍那么"丰富"——比如拿不到短信App界面上的完整对话记录——但对于转发验证码和来电通知这个场景来说,已经足够实用了。功能边界收窄一点,换来的是稳定性和合规性的大幅提升。

3. 权限、保活、通道:跑通之前必须处理的三道坎

比功能逻辑更早拦在面前的是三件跟系统打交道的事:权限申请、后台存活、通道连通。这三件事不搞定,代码写得多漂亮都白搭。我自己在这里踩的坑,比在核心逻辑上踩的还要多。

3.1 需要申请的权限清单

我用到的权限分两类,一类是运行期动态权限,一类是需要跳设置页单独确认的特殊权限。动态权限包括:接收短信、读取短信、读取电话状态;Android 13以上还把通知权限单独列了出来,想弹出"转发成功"之类的本地提示也必须申请。这些权限必须在应用启动时逐个申请,并且要在代码里做好"用户拒绝之后怎么办"的逻辑,不能假定用户一定给。

这里有个容易被忽略的点:就算用户把所有权限都点了允许,部分系统在应用每次更新之后,依然可能把某些敏感权限重置成拒绝状态。转发系统是长期挂在后台的,一旦权限被重置而用户没有察觉,就变成了"应用还在跑,但短信已经收不到了"。所以我在应用里加了一个健康检查机制,定期检测关键权限是否还在,不在就弹提醒,而不是等用户自己发现消息没推过来。

3.2 Android 13/14的权限变化

Android 13开始通知权限单独列出来了,Android 14又在短信权限上做了更严格的默认限制。我在一台Android 14的真机上调试时,发现光在Manifest里声明权限还不够,还必须引导用户进入系统设置,把应用设为默认短信应用,或者在应用列表里手动打开"允许读取短信"这一类额外开关。这个问题不真机调试根本发现不了,因为在Android 12以下根本没有这个开关。

适配思路很简单:启动时做一次能力探测,读取当前系统的实际权限状态,而不是只看应用自己声明的权限。如果发现系统版本比较高,就直接弹出引导页,一步步告诉用户要到哪个设置菜单点哪个选项。全程不要试图绕过系统设置,强制在应用内用代码去"激活"短信读取权限的做法,在新的Android版本上基本都行不通了。

3.3 后台存活是最大的拦路虎

权限给了,代码没问题,但锁屏半小时后转发就断了,这是自部署方案最经典的翻车现场。原因很简单:设备厂商对后台应用普遍有激进的管理策略,省电优化会把不活跃的应用从进程里杀掉。我的解决思路是几个手段叠加:一是把应用加入电池优化的白名单,也就是请求用户关闭对它的电池限制;二是用一个前台服务把进程托住,让系统知道这个应用正在执行用户可见的任务;三是在厂商自带的"自启动管理"和"后台运行权限"页面里手动放行。

这个组合拳打完之后,我实测放在抽屉里一周不断线,中间还经历了自动更新和重启,服务都能自己拉起来。注意,不同厂商的设置路径差得很远,遇到断线先别急着怀疑代码,先在设置里把所有跟"省电""后台""自启动"相关的开关都过一遍。如果你用的是一台原生Android设备,这条路上的坑会少很多,但国产设备用户必须多留个心眼。

3.4 转发的通道连通性测试

通道这块我觉得应该在一开始就跑通一个最小闭环:手机端配好转发地址,手动触发一条测试内容,确认能到达目标设备,再继续往下做。不然最后全部功能联调时,你根本分不清是短信没进来、还是转发接口写错了、还是网络不通。最简单的方式是先在本机起一个HTTP接收端,把一次转发链路走通,后面再换正式通道,排错成本会小很多。

我在项目里内置了"发送测试消息"的按钮,填好通道配置后点一下,目标端没有收到就直接看本地转发日志,几秒钟就能定位问题出在哪一层。这一步虽然简单,却是整个部署流程里最值得先做的事。

4. 规则引擎:把营销短信和骚扰来电挡在转发门外

如果只是把每条短信和每个来电都转发出来,这套系统的体验会非常糟糕。我的副卡每天收到的营销短信少说二十条,要是每条都推过来,和没有过滤直接看手机几乎没有区别。所以规则引擎是真正决定方案可用性的部分,也是我花时间最多的地方。

4.1 匹配维度:号码、关键词、时段,缺一不可

我设计了三个主要维度。号码维度支持精确匹配和前缀匹配,适合设置白名单号码段;关键词维度针对短信正文,比如"验证码""账单""快递"这类高价值的词;时段维度则是为了区分白天和深夜,晚上十一点后只放行白名单,其他的一律不打扰。三个维度之间支持"与""或"组合,用户可以在配置里按自己的习惯组规则。

以我自己为例,交通银行的验证码短信号码每次都不同,但前几位固定,就建了一条前缀白名单;快递的取件通知关键词比较固定,就建了一条关键词放行规则。实际效果是白天大部分营销短信直接被默认规则挡掉,只剩少量需要手动处理,到了深夜又进一步收紧,睡眠质量明显好了。

4.2 黑白名单不是靠直觉就能定好的

黑白名单看起来简单,实际用起来有两个容易踩的坑。第一个坑是拦截类关键词太宽泛,比如把"通知"作为拦截词,可能连银行动账通知一起拦了;第二个坑是白名单覆盖不完整,验证码短信号码经常不一样,只有开头几位固定,需要前缀匹配而不是精确匹配。我最后采用的方式是默认规则加自定义规则叠加,默认规则用来处理覆盖面大的高频场景,自定义规则用来处理细枝末节。这个设计的好处是,你不用把每条短信都搬出来检查一遍,只需要处理少数漏网之鱼。

4.3 默认不转发:这个反直觉规则让我少收一半垃圾推送

最开始做规则引擎的时候,我一度是"默认全转发,匹配到就过滤掉",实际效果很糟糕:关键短信没少漏,垃圾短信也没少多少。后来我整个逻辑反过来了:默认什么都不转发,只有命中某条放行规则的才推出去。这个改动让推送量直接降了一个数量级,但代价是刚开始漏了一些没有预料到的短信类型,比如快递驿站的取件通知。解决办法也很朴素,遇到漏报就补一条规则进去,磨合一周左右规则就基本稳定了。

这个"默认拒绝"的设计,和防火墙上默认拒绝入站连接是一个道理:新增白名单的成本,远比从海量垃圾里挑出有用信息要低得多。而且规则越多,默认拒绝的收益越大,因为你永远不用考虑"排除项"会不会误伤关键消息。

5. 转发通道实测:HTTP回调、IM机器人、邮件兜底怎么选

规则筛选出来内容之后,更关键的决策在于通过什么通道送到用户手里。我同时实现了三种通道,实测下来各自适用场景差异很明显,直接把结论和配置要点写在这里。

5.1 HTTP回调:最灵活,但必须端到端加密

HTTP回调是最直接的方案:手机端把消息封装成一个JSON请求,POST到配置的回调地址,服务端自行处理。JSON结构我设计得比较简单清晰,包含来源号码、类型、消息内容、时间戳和命中的规则标签。这个方案的灵活性在于服务端完全自主,你可以接任何能收HTTP的服务,配合脚本可以让消息自动触发后续流程,比如把验证码自动填入某个登录页面。短板则是回调地址如果走公网,等于把消息内容暴露在网络上,至少要走HTTPS,并且接口要带鉴权,不能裸奔。

我自己的习惯是,回调地址只接受带令牌的请求,令牌通过配置文件单独下发,不硬编码进应用。服务端收到请求后先校验令牌,不合法直接拒绝,合法才进入后续处理。这套流程和南向接口的鉴权思路一样,虽然简单,但能挡住绝大多数扫描请求。

5.2 即时通讯机器人:体验最顺,但依赖平台的推送能力

第二种通道是走即时通讯机器人,把消息推送到自己常用的聊天工具里。体验上是所有方案里最顺滑的,验证码来了就是一条消息,不用专门打开另一个App,我在地铁上收快递通知的场景就是这么解决的。实现上本质还是HTTP回调,只是把回调地址换成机器人接口。实际使用时要优先选那些通道稳定、官方接口开放的IM平台,消息到达率才更有保障。依赖第三方平台的同时也要接受它的限制:个别平台会限制消息频率,短时间推送太密有可能被限流。我建议如果主通道选IM,就尽量把规则收敛一点,把推送量控制在每天几十条以内,基本不会触发限制。

5.3 邮件兜底:慢,但胜在可靠

邮件通道是我预留的兜底方案。为什么说兜底?因为邮件推送的实时性明显不如IM,端到端延迟经常在几十秒到几分钟之间,验证码类消息等不起。但邮件有一个不可替代的优势:可靠、不过期、可检索。IM消息如果被群组折叠或者被误删,很容易就找不回来了,邮件则可以作为长期归档。所以我的配置里,验证码类短信会同时推IM和邮件,IM负责快,邮件负责留底。如果你需要"以后可能追溯某时间收到过什么短信"这种场景,邮件通道的价值就会体现出来。

5.4 重试与去重:转发系统的两个隐形需求

通道跑通之后我发现了两个之前没考虑的问题。一是消息可能发送失败,比如回调超时或者网络瞬断,这时需要自动重试,但重试次数必须有限制,不然一晚上的重试请求能把接收端打挂。二是消息可能会重复,系统广播在个别机型上会触发两次,同一个短信可能被转发两遍。解决办法是在接收端做去重:用源号码加消息内容加时间戳算一个唯一键,短时间内只接受一次。这两个机制我现在不管换哪个通道都会默认带上,可以算作转发系统的基本盘。

三种通道实测下来各有优劣,整理了一个简单对比供参考:

通道类型实时性可靠性部署复杂程度适用场景
HTTP回调高中,取决于服务端需要自建接口对接自建服务,灵活性要求高
IM机器人很高较高,依赖平台需要机器人配置日常推送主力,体验最佳
邮件低高很低归档、兜底、非紧急消息

6. 部署在闲置旧手机上的完整过程与稳定性总结

整个项目从零到稳定运行,我自己走了一遍完整的部署流程。这里把过程完整记录下来,包括设备和系统的选择、安装步骤和几个排查异常的经历,照着走基本能少踩一半的坑。

6.1 设备选型:旧手机不是越强越好

接收短信和来电对性能要求极低,所以根本不需要拿主力机来跑。我用了一台好几年前的老安卓机,系统版本正好卡在Android 11,选它的理由有三:版本不算太老,权限模型还没有变得最严格,但短信广播的读取机制已经成熟;硬件省电,连续待机一个星期没有问题;系统干净,不会预装一堆抢占资源的应用。如果你手里的是Android 8以下的设备,建议还是放弃,老系统的兼容性和安全补丁都比较成问题,而且很多新版依赖库已经不往下兼容了。

6.2 从源码到安装的完整链路

部署的第一步是拿到安装包。有动手能力的可以直接从源码编译,更省事的则是使用项目发布的预编译版本,前提是确认签名和来源。安装完成之后进入应用,先做权限引导,随后配置转发规则和通道,最后用应用内置的测试功能发一条测试内容。整个链路走通的关键,是每完成一步就验证一步:权限授予后用测试短信验证接收,通道配置后用测试消息验证推送,规则写好后再用实际短信验证过滤。我见过不少人在这一步偷懒,把所有配置一次性填完,结果出了问题根本不知道往哪个方向排查。

6.3 稳定性观察与日志排查

我把这套方案部署在一台老设备上连续运行了将近一个月,中间遇到的最典型问题是凌晨两三点转发中断,日志停在某个网络请求的位置。排查过程先怀疑是网络超时,看了日志发现其实是设备的深度休眠切断了网络,消息在进程里排队但完全出不去。定位到问题后,解决方式是在前台服务里定期申请唤醒锁,同时把推送逻辑设计成在应用进程存活时可持续触发。另一个容易忽略的点是SIM卡被系统识别为"无服务"的情况,设备放在抽屉里、靠墙角的位置,偶发信号漂移会导致接收延迟,这个属于物理环境问题,把设备放到信号稳定的位置就好。

6.4 常见异常与处理方式

试运行期间收集了几个高频异常,整理成了一张表,单看每一条都不起眼,但组合起来能省很多排查时间:

异常现象可能原因处理方式
收不到短信转发未设为默认短信应用或读短信权限缺失检查系统设置中的应用权限
一段时间后转发停止被系统省电策略杀掉加入电池白名单和厂商自启动白名单
消息推了两次高优先级接收器造成回调重复接收端按唯一键去重
打不通的电话没推号码返回为空或带前缀规则里做号码清洗与空号过滤
推送延迟明显设备深度休眠或通道链路慢前台服务保活并做网络长连接优化

7. 安全与隐私:自部署方案必须守住的底线

短信和来电属于高度敏感的个人信息,把这类数据从一个设备挪到另一个设备,本身就引入了新的风险面。所有自部署方案的隐私优势,都必须建立在自身安全措施到位的前提下,这一点我在实际使用中感触很深。

7.1 传输加密和访问鉴权,两件事缺一不可

转发通道只要不是纯本地回环,就必须考虑传输安全。走公网的接口一定要用加密连接,不能裸用明文HTTP把验证码推来推去。接口鉴权也一样,回调地址如果没有任何令牌校验,等于对互联网开放了一个短信落地窗。接收端必须校验来源请求的令牌,令牌本身也要按环境变量或配置文件方式隔离,不要硬编码到代码里。我自己的经验是,宁可先把这两件事配好再上线,也不要先跑通再补。消息一旦泄露,事后补救是弥补不了已经发生的风险的。

7.2 数据保留策略:转发不等于无限期存证

这条线我自己先立好规矩:手机端只保留近七天的转发日志,用于排查问题;接收端同样周期性清理消息缓存,不做长期留痕。很多人做这类系统会下意识把数据存下来,觉得"存着以后有用",但短信数据存得越久,被攻破或者被误用的损失就越大。合理的做法是默认不带数据库就尽量不建,临时缓存全部加密,过期就彻底清理,日志文件也定期轮转,避免单文件无限膨胀。

7.3 合规边界:这套系统是给自己用的,不是给别人用的

最后一点可能听起来像废话,但我还是想强调:这套方案的使用范围,应该是你自己的设备、自己的号码、自己授权过的场景。任何形式的未经授权对他人设备进行转发、监听,都属于严重问题。我在项目的文档里也明确写清了使用边界,不建议把这个方案用于任何超出自身设备管理的用途。

在实际使用中我感受到,自部署这类敏感消息转发方案,最大的安全感其实来自"所有数据都在自己可控的路径里流动"这件事。把权限、加密、留存边界都管好,这套转发系统才能真正用得踏实。如果你也经常被验证码断联困扰,手里又正好有一台旧安卓机,不妨按这个思路搭一套试试。第一次部署的完整链路大约需要半天时间,之后基本就是一劳永逸。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询