前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android监听手机短信的示例代码

Android监听手机短信的示例代码

作者头像
砸漏
发布2020-10-26 22:16:01
4.6K0
发布2020-10-26 22:16:01
举报
文章被收录于专栏:恩蓝脚本

本文介绍了Android监听手机短信的示例代码,分享给大家,具体如下:

以下情况可能会导致短信拦截失败:

  1. 小米,360等品牌手机拦截短信,短信的优先级给了系统
  2. 用户禁用短信权限
  3. 手机连接电脑,被电脑端的手机助手类软件截获
  4. 手机内装有QQ通讯录之类的管理联系人,短信的应用,被截获.

前提–权限:

代码语言:javascript
复制
<uses-permission android:name="android.permission.RECEIVE_SMS"   
</uses-permission  
<uses-permission android:name="android.permission.READ_SMS"   
</uses-permission  

定义短信广播接收者

代码语言:javascript
复制
public class SMSBroadcastReceiverextends BroadcastReceiver{

  private static OnReceivedMessageListener mOnReceivedMessageListener;
  public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";

  public SMSBroadcastReceiver(){
    super();
  }

  @Override
  public void onReceive(Context context, Intent intent){
    if (intent.getAction().equals(SMS_RECEIVED_ACTION)) {
      Object[] pdus = (Object[]) intent.getExtras().get("pdus");
      for(Object pdu:pdus) {
        SmsMessage smsMessage = SmsMessage.createFromPdu((byte [])pdu);
        String sender = smsMessage.getDisplayOriginatingAddress();
        String content = smsMessage.getDisplayMessageBody();
        long date = smsMessage.getTimestampMillis();
        Date tiemDate = new Date(date);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(tiemDate);
        //过滤不需要读取的短信的发送号码
        if ("106902780116481".equals(sender)) {
          mOnReceivedMessageListener.onReceived(getDynamicPassword(content));
          abortBroadcast();
        }
      }
    }
  }

  public interface OnReceivedMessageListener{
    void onReceived(String message);
  }

  public void setOnReceivedMessageListener(OnReceivedMessageListener onReceivedMessageListener){
    this.mOnReceivedMessageListener = onReceivedMessageListener;
  }

  /**
   * 从字符串中截取连续6位数字组合 ([0-9]{" + 6 + "})截取六位数字 进行前后断言不能出现数字 用于从短信中获取动态密码
   * @param str 短信内容
   * @return 截取得到的6位动态密码
   */
  public String getDynamicPassword(String str){
    // 6是验证码的位数,一般为六位
    Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{" + 6 + "})(?![0-9])");
    Matcher m = continuousNumberPattern.matcher(str);
    String dynamicPassword = "";
    while (m.find()) {
      dynamicPassword = m.group();
    }
    return dynamicPassword;
  }
}

注册广播

代码语言:javascript
复制
SMSBroadcastReceiver = mSMSBroadcastReceiver = new SMSBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter(SMSBroadcastReceiver.SMS_RECEIVED_ACTION);
intentFilter.setPriority(Integer.MAX_VALUE);
this.registerReceiver(mSMSBroadcastReceiver, intentFilter);
ToastManager.getInstance().showLongToast("注册短信监听");

mSMSBroadcastReceiver.setOnReceivedMessageListener(new SMSBroadcastReceiver.OnReceivedMessageListener() {
 @Override
 public void onReceived(String message){
 //do something
 }
});

方式二:监听短信数据库

内容提供者中对外通信方式有3种:

方式1:定义为Activity的内部类,直接在onChang()方法中处理业务逻辑,比如收到短信之后设置给EditText

  1. 优点:方便
  2. 缺点:耦合度高,复用性差

方式2:定义接口,Activity实现这个接口,拿到回调,处理业务逻辑

  1. 优点:耦合度低,复用性高
  2. 缺点没用充分利用Handler资源

代码如下:

代码语言:javascript
复制
/**
 * Created by wxw on 2016/9/24 10:34
 * function: 监听短信数据库
 * e-mail:wangxw725@163.com
 */
public class SmsContentObserverextends ContentObserver{
  private Cursor cursor = null;
  private Context mContext;
  private String[] projection = new String[]{"_id","body"};
  private OnMessageObservedListener mOnMessageObservedListener;

  public SmsContentObserver(Context context,Handler handler){
    super(handler);
    this.mContext = context;
  }

  public interface OnMessageObservedListener{
    void onObservedMessage(String message);
  }
  public void setOnMessageObservedListener(OnMessageObservedListener onMessageObservedListener){
    this.mOnMessageObservedListener = onMessageObservedListener;
  }

  @Override
  public void onChange(boolean selfChange){
    super.onChange(selfChange);

    cursor = mContext.getContentResolver().query(Uri.parse("content://sms/inbox"), projection,null, null, "_id desc");

    if (cursor != null && cursor.getCount()   0) {
      cursor.moveToNext();
      int smsbodyColumn = cursor.getColumnIndex("body");
      String smsBody = cursor.getString(smsbodyColumn);
      mOnMessageObservedListener.onObservedMessage(getDynamicPassword(smsBody));
    }
    cursor.close();
  }

  private String getDynamicPassword(String str){
    Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{" + 6 + "})(?![0-9])");
    Matcher m = continuousNumberPattern.matcher(str);
    String dynamicPassword = "";
    while (m.find()) {
      dynamicPassword = m.group();
    }
    return dynamicPassword;
  }
}

方式3:通过Handler发送消息,在Activity中进行业务逻辑处理

代码如下:

代码语言:javascript
复制
/**
 * Created by wxw on 2016/9/24 10:34
 * function: 监听短信数据库
 * e-mail:wangxw725@163.com
 */
public class SmsContentObserverextends ContentObserver{
  private Cursor cursor = null;
  private Context mContext;
  private Handler mHandler;
  private String[] projection = new String[]{"_id","body"};

  public SmsContentObserver(Context context,Handler handler){
    super(handler);
    this.mContext = context;
    this.mHandler = handler;
  }

  @Override
  public void onChange(boolean selfChange){
    super.onChange(selfChange);
    cursor = mContext.getContentResolver().query(Uri.parse("content://sms/inbox"), projection,null, null, "_id desc");

    if (cursor != null && cursor.getCount()   0) {
      cursor.moveToNext();
      int smsbodyColumn = cursor.getColumnIndex("body");
      String smsBody = cursor.getString(smsbodyColumn);
      mHandler.obtainMessage(1,getDynamicPassword(smsBody)).sendToTarget();
    }
    cursor.close();
  }

  private String getDynamicPassword(String str){
    Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{" + 6 + "})(?![0-9])");
    Matcher m = continuousNumberPattern.matcher(str);
    String dynamicPassword = "";
    while (m.find()) {
      dynamicPassword = m.group();
    }
    return dynamicPassword;
  }
}

注册观察者

代码语言:javascript
复制
smsContentObserver = new SmsContentObserver(this, smsHandler);
getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, smsContentObserver);

handler中处理消息

代码语言:javascript
复制
private Handler smsHandler = new Handler(){
 @Override
 public void handleMessage(Message msg){

 switch (msg.what){
  case 0:
  ......
  break;
  case 1:
  LogUtils.x("Activity收到了短息码:"+(String)msg.obj);
  lf.mEtPassword.setText((String)msg.obj);
  break;
 }
 }
};

注销观察者

代码语言:javascript
复制
@Override
protected void onDestroy(){
 super.onDestroy();
 ......
 if(smsContentObserver!=null){
 getContentResolver().unregisterContentObserver(smsContentObserver);
 smsContentObserver = null;
 }
}

遗留问题

观察者会多次回调onChang方法()

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
短信
腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档