欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-05-26 21:46:32
本文介绍了android监听手机短信的示例代码,分享给大家,具体如下: 以下情况可能会导致短信拦截失败: 小米,360等品牌手机拦截短信,短信的优先级给了系统...

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

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

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

前提--权限:

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

定义短信广播接收者

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;
  }
}

注册广播

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资源

代码如下:

/**
 * 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中进行业务逻辑处理

代码如下:

/**
 * 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;
  }
}

注册观察者

smscontentobserver = new smscontentobserver(this, smshandler);
getcontentresolver().registercontentobserver(uri.parse("content://sms/"), true, smscontentobserver);

handler中处理消息

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;
 }
 }
};

注销观察者

@override
protected void ondestroy(){
 super.ondestroy();
 ......
 if(smscontentobserver!=null){
 getcontentresolver().unregistercontentobserver(smscontentobserver);
 smscontentobserver = null;
 }
}

遗留问题

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

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