Android转发短信给QQ机器人

背景

公司同事身处不同省份,都需要访问一个甲方的系统,登录系统需要短信验证码。手机在技术手上,经常打断工作去看验证码实在是影响工作效率,因此结合前面开发的QQ机器人,结合APP实现转发短信到服务器,再由QQ机器人发到群里的功能。

前提

公网IP
非鸿蒙系统(实现方式不同)
安卓版本低于8.0(API 26)(对静态广播有限制)

目前发现的问题

APP退出时间长了以后收不到静态广播,推测是被回收掉了。
傻瓜式解决方案:APP置于前台不退出
根源式解决方案:进程保活

技术实现

BroadcastReceiver + socket + python
因为是给QQ机器人接入的新功能,所以采用socket的方式。
换个思路也可以做一个API,接收到短信以后保存到数据库里,通过python定时访问数据库检查是否有新的短信,有就发出来。考虑到验证码的时效性,这个查询的周期会比较短,一个程序定时高频率操作数据库感觉不够奈斯。

代码

Android部分

main.class随便写写就行了,反正也不用。

SmsRecevier.class
静态注册一个BroadcastReceiver,监听短信广播,然后通过socket发送给服务器。
静态注册的广播,APP退出以后会继续工作。

public class SmsRecevier extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();//通过getExtras()方法获取短信内容
        if (bundle != null) {
            Object[] pdus = (Object[]) bundle.get("pdus");//通过关键词“pdus”从Bundle实例中获取到短信字节数组—pdus
            if (pdus == null) {
                return;
            }
            SmsMessage[] messages = new SmsMessage[pdus.length];//把短信字节数组—pdus转换进->SmsMessage[]

            for (int i = 0; i < messages.length; i++) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    String format = bundle.getString("format");
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format);
                } else {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                }
                try {
                    String msgStr = messages[i].getMessageBody();//短信内容
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String t1 =simpleDateFormat.format(new Date(messages[i].getTimestampMillis())) //发送时间
                    String s1 =messages[i].getOriginatingAddress()) //发件人手机号
                    transport(msgStr);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void transport(String m) {
        final String message = m + "\r\n";//数据的结尾加上换行符才可让服务器端的readline()停止阻塞
        try {
            new Thread() {
                @Override
                public void run() {
                    try {
                        String host = "1.2.3.4";
                        int port = 1234;
                        Socket socket = new Socket(host, port);
                        if (socket.isConnected()) {
                            OutputStream outputStream = socket.getOutputStream();
                            outputStream.write(message.getBytes("UTF-8"));
                            outputStream.flush();
                            outputStream.close();
                            socket.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    super.run();
                }
            }.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

AndroidManifest.xml
添加权限和静态注册广播

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>

	<application
      	…………
        <receiver android:name="com.xxx.SmsRecevier"  android:exported="true">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
                <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
            </intent-filter>
        </receiver>
    </application>

这条权限不能少,没有这个权限无法读取信息内容:

<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>

pythton部分

python+go-cqhttp搭建自动回复QQ机器人中的自动回复部分差不多,只是如果手机和服务器不在同一个局域网下,那么服务器上的socket监听的IP地址要写成服务器的公网地址,和BroadcastReceiversocket发送消息的IP地址一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值