前几天手机升级到 Android 7.0,发现获取闪讯密码客户端闪退了,我怀疑是运行时权限的问题,因为是必备的软件,所以想自己重新写一个。

网上搜了一下,直接发短信是用SmsManger实现:

SmsManager smsManager = SmsManager.getDefault();
        PendingIntent sentIntent = PendingIntent.getBroadcast(this, 0, new Intent(SMS_SEND_ACTION), 0);
        PendingIntent deliveryIntent = PendingIntent.getBroadcast(this, 0,
                new Intent(SMS_DELIVERED_ACTION), 0);
        smsManager.sendTextMessage("1065930051", null,
                "mm", sentIntent, deliveryIntent);

第一个参数是短信接收方;第二个参数是短信中心号码,可以不写;第三个参数是短信内容;后两个参数是两个PendingIntent,需要用到两个BroadcastReceiver,用来监听发送状态。

短信发出去了,接下来的任务是读取新收到的短信,截取验证码和日期。需要用一个广播接收器:

public class SmsReceiver extends BroadcastReceiver {
    private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
    private static final String TAG = "SmsReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "onReceive: run");
        // TODO Auto-generated method stub
        if(SMS_RECEIVED.equals(intent.getAction())){
            Bundle bundle = intent.getExtras();
            if(bundle != null){
                Object[] pdus = (Object[])bundle.get("pdus");
 
                SmsMessage[] msg = new SmsMessage[pdus.length];
                for(int i = 0 ;i<pdus.length;i++){
                    msg[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
                }
                SmsMessage sx = msg[0];//获取闪讯短信
                String password = sx.getDisplayMessageBody().substring(18,24);
                String dateStr = sx.getDisplayMessageBody().substring(28,47);
                long date = getLongFromString(dateStr);//伪代码
                //保存数据
                SharedPreferences.Editor editor = context.getSharedPreferences("data", Context.MODE_PRIVATE).edit();
                editor.putString("password", password);
                editor.putLong("date", date);
                editor.apply();
                //更新UI
                abortBroadcast();
                MainActivity.sPasswordText.setText(password);
                MainActivity.sUsableText.setText("密码有效");
            }
        }
    }
    }
}

收到的短信是pdus数据,具体不懂,SmsMessage.createFromPdu这个方法返回收到的短信,我的理解是msg[0]应该就是闪讯的验证码短信,没有对号码判断,应该没大问题。

另外收到短信之后,我不知道怎么在SmsReceiver里面更新MainActivity里这两个text,本来写了个回调接口,实现不了,不知道为什么。然后干脆把那两个TextView变静态的,直接在SmsReceiver里改了… 不知道这么写有没有问题,不过想要的功能实现了。

目前感觉不错,我另外加了验证码是否过期的提示,感觉比官方的好用。

源码在这里 Source