安卓短信转发方案

前言

鉴于现在国内运营商的状态,水果的 iPhone 都开始支持双卡了。而事实上双卡双待中的“待”,在大多数情况下,并不需要做在同一个手机上。

一个显而易见的解决方案是:在家里放置一个廉价安卓手机负责转发。对于来电可以设置呼叫转移,那么我们的关注点就在于如何转发短信,以及如何远程发送短信了。

本文给出了一些折腾记录供参考。

设备:斐讯安卓4.0垃圾机(四年前电信话费充值送的垃圾)、红米2垃圾机(淘宝180块包邮)、树莓派3B。

IFTTT

该方案对于性能还行的手机可能可以正常工作。需要设置一些权限,保持IFTTT活着。

我也尝试过这种方式,但是经常漏短信。在配置还算可以的手机上似乎运行的没问题。

Android 4.0 + RaspberryPi

本方案中的安卓手机性能太炸以至于跑不起来最新版IFTTT和Tasker。

于是将其ROOT后连接到树莓派上,树莓派端以一定间隔adb pull /data/data/com.android.providers.telephony/databases/mmssms.db,然后使用 SQLite 库读取短信,并通过 Telegram API 转发消息。

而远程发送短信做起来就有点麻烦。

首先要通过 Telegram 接收指令。这里没有使用封装好的库,直接请求裸的HTTP API。设置Telegram Bot的Callback和进内网的NGINX代理,使内网中可以接收到Telegram的消息。

做身份验证之后可以直接调用命令 adb shell service call isms 5 s16 “+8613000000000” i32 0 i32 0 s16, “SMS CONTENT”

但是这种方法只能调用主卡发送,如果想将两张卡绑定到两个人的Telegram账号,则需要对另一张卡单独处理。这里使用模拟点击的方法。
模拟点击的第一步是调用短信的action:
adb shell am start -a android.intent.action.SENDTO -d sms:+8613000000000 –es sms_body “SMS CONTENT” –ez exit_on_sent true -S
之后通过 adb shell input keyevent 61 这种模拟键盘事件,通过按Tab和方向键控制光标,然后点击回车发送。

Python 版完整代码见: https://github.com/ihciah/AndroidSMSRelay

Golang 版(只含转发部分): https://github.com/suikammd/smsrelay

Tasker

Tasker是一个类似 IFTTT 但定制空间大得多的 App 。该 App 占用资源低并且生命力极强2333,在给了足够权限后可以不死(测试机为红米2)。

方案2如果不愿折腾,只想用手机,那么这个方案可以考虑。

首先我们需要创建一个事件,即收到短信。然后我们需要设定短信来了之后的操作。

这里依旧使用Telegram接口。根据Telegram Bot API,我们可以很容易地通过请求 https://api.telegram.org/botxxxxxxxxxxxxxxx/sendMessage?chat_id=0000000&text=SMS 来发送短信。
然而这种方式存在两个问题:

a. 网络连接问题

由于众所周知的问题,Telegram API 并不能直接连接。方案2中由于是树莓派,所以分分钟 Tinc 搭梯子;但是安卓手机并不是都能跑小飞机的。

针对问题a:要么手机上运行一个小飞机,要么为 Telegram API 搭建一个反向代理。后者有点复杂但是较为通用,其他场景中也可以使用,包括应用到方案2中替代 Tinc。我们仅仅需要转发一下请求,这是十分微量的消耗,开一个VPS再搭建代理显然有点杀鸡用牛刀了。

这里我们为Telegram API搭建一个反向代理。

可以使用阿里云提供的Function Compute,类似AWS Lambda的东西。这个东西是按使用付费,由于有每月免费额度,所以只需要支付流量费(0.8元/GB)。

创建时,区域选择香港(或其他非大陆地区,但香港延迟较低),语言选择Python2.7,模板选择Flask,勾选HTTP触发器。

创建完后将本文附的代码贴进去覆盖即可。之后使用只需要对 https://xxxxxx.cn-hongkong.fc.aliyuncs.com/xxxxx/proxy/xxxx/xxxx/botAAAAA/sendMessage 发送请求即可。

Telegram API反向代理: https://gist.github.com/ihciah/665fd43b597141fa93a7c85340917835

ps: 腾讯云也有类似服务,但是可选区域只有国内,所以不满足需求。

b. 短信内容包含特殊字符需要转义后拼接

针对问题b:Tasker自带的 HTTP POSTVariable URLEncode 我一直没搞对,总是有转义问题,所以这里干脆直接写JavaScript,使用 XMLHttpRequest 配合 encodeURIComponent 即可。

Tasker发送脚本:https://gist.github.com/ihciah/218c1f770d4e0a9bd4666a5f593977d9

另:MIUI对于短信读取权限有BUG,即使给足了权限,app也无法读取短信。解决方案是刷机(笔者刷了CM)。
来,跟我读:小 米 垃 圾 !