android拦截短信并提取内容

来源:互联网 发布:resttemplate json 编辑:程序博客网 时间:2024/05/16 11:17

我们经常需要用手机号和短信验证码来登录,如果把短信拦截并把里面的验证码读取出来自动写在输入框上去,这样就比较炫了。虽然这个还是敌不过360等软件拦截器,但对一般的还可以的话,就先收藏了

转自http://www.eoeandroid.com/forum.php?mod=viewthread&tid=196130

import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telephony.SmsMessage;
import android.util.Log;

public class SMSCodeBroadcast extends BroadcastReceiver {
        private AfterReceive afterReceive;
        private  SmsContentObserver smsContentObserver;
        private  int index = 0;
        private Context context;

//如果读取成功的话就调用回调函数,同时取消观察者模式
    private Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                    String smsContent = (String)msg.obj;
                    index = index+1;
                    if(index==1){
                            if(smsContent!=null&&!"尊敬的用户,您本次登录终端XXXX的验证码为:323250,20分钟内有效。请尽快验证!".equals(smsContent)){
                                    afterReceive.autoFill(smsContent.substring(smsContent.indexOf(":")+1,smsContent.lastIndexOf(",")));
                                    // this.abortBroadcast();
                                     context.getContentResolver().unregisterContentObserver(smsContentObserver);
                            }else{
                                    index =0;
                            }
                           
                    }
                    super.handleMessage(msg);
            }
    };
        
    public SMSCodeBroadcast(){
            
    }
        public SMSCodeBroadcast(Context context,AfterReceive afterReceive) {
                this.afterReceive = afterReceive;
                this.smsContentObserver = new SmsContentObserver(context, new Handler());
                this.context = context;

//注册观察者。观察短信数据库变化
                context.getContentResolver().registerContentObserver(
                   Uri.parse("content://sms/"), true, smsContentObserver);
               
               
        }

//广播的回调函数,读取到短信内容将返回到我们要显示的输入框中
        public interface AfterReceive {
                void autoFill(String code);
        }
        

        @Override
        public void onReceive(Context context, Intent intent) {
                // TODO Auto-generated method stub
                Bundle bundle = intent.getExtras();
               
                Object messages[] = (Object[]) bundle.get("pdus");
                SmsMessage smsMessage[] = new SmsMessage[messages.length];

//这里面主要是截取我们想要的短信内容,
                for (int n = 0; n < messages.length; n++) {
                        smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
                        String sender = smsMessage[n].getOriginatingAddress();
                        if ((sender.equals("106575550014")||sender.equals("106573400007")) &&smsMessage[n].getMessageBody().contains("ESOP")) {
                                String smsContent = smsMessage[n].getMessageBody();
                                Message message = new Message();
                                message.obj = smsContent;
                                handler.sendMessage(message);
                                
                                
                        }
                        System.out.println(smsMessage[n].getMessageBody());
                }
        }

//观察者
         public class SmsContentObserver extends ContentObserver {

            private Context context;
            public SmsContentObserver(Context context,Handler handler) {
                    
                super(handler);
                this.context  =context;
            }
            
            @Override
            public void onChange(boolean selfChange) {
                super.onChange(selfChange);
                // 读取收件箱中指定号码的短信
                /*cursor = managedQuery(Uri.parse("content://sms/inbox"),
                        new String[] { "_id", "address", "read" },
                        " address=? and read=?",

                        new String[] { "10086", "0" }, "date desc");

                    cursor.moveToFirst();

                    String body=cursor.getString(3);

                    if(body.equals("AAA")){


                    }*/
                    
                    Message message = new Message();
                        message.obj = getSmsInPhone();
                        handler.sendMessage(message);
                    
                }
            

//获取短信中最新的一条未读短信,大家可以去查查,一些字段
            public String getSmsInPhone()   
            {   
                final String SMS_URI_ALL   = "content://sms/";     
                final String SMS_URI_INBOX = "content://sms/inbox";   
                final String SMS_URI_SEND  = "content://sms/sent";   
                final String SMS_URI_DRAFT = "content://sms/draft";   
                  
                StringBuilder smsBuilder = new StringBuilder();   
                  
                try{   
                    ContentResolver cr = context.getContentResolver();   
                    String[] projection = new String[]{"_id", "address", "person",   
                            "body", "date", "type"};   
                    Uri uri = Uri.parse(SMS_URI_ALL);   
                    Cursor cur = cr.query(uri, projection, "read = ?", new String[]{"0"}, "date desc");   
              
                    if (cur.moveToFirst()) {   
                        String name;   
                        String phoneNumber;         
                        String smsbody;   
                        String date;   
                        String type;   
                        
                        int nameColumn = cur.getColumnIndex("person");   
                        int phoneNumberColumn = cur.getColumnIndex("address");   
                        int smsbodyColumn = cur.getColumnIndex("body");   
                        int dateColumn = cur.getColumnIndex("date");   
                        int typeColumn = cur.getColumnIndex("type");   
                        
                        do{   
                            name = cur.getString(nameColumn);               
                            phoneNumber = cur.getString(phoneNumberColumn);   
                            smsbody = cur.getString(smsbodyColumn);   
                              
                            SimpleDateFormat dateFormat = new SimpleDateFormat(   
                                    "yyyy-MM-dd hh:mm:ss");   
                            Date d = new Date(Long.parseLong(cur.getString(dateColumn)));   
                            date = dateFormat.format(d);   
                              
                            int typeId = cur.getInt(typeColumn);   
                            if(typeId == 1){   
                                type = "接收";   
                            } else if(typeId == 2){   
                                type = "发送";   
                            } else {   
                                type = "";   
                            }   
                            smsBuilder.append(smsbody);   
                           
                            if(smsbody == null) smsbody = "";     
                            break;
                        }while(cur.moveToNext());   
                    } else {   
                        smsBuilder.append("no result!");   
                    }   
                        
                } catch(SQLiteException ex) {   
                    Log.d("SQLiteException in getSmsInPhone", ex.getMessage());   
                }   
                return smsBuilder.toString();   
            }
         
        }
}


在我们想要显示的Activity中
        /**
     * 註冊短信监听器
     */
        private void registerSMSReceiver() {
                IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
                filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);// 设置优先级最大
                mReceiver = new SMSCodeBroadcast(this,new AfterReceive() {
                        
                        @Override
                        public void autoFill(String code) {
                                // TODO Auto-generated method stub
                                unRegisterSMSReceiver();
                                mSmsCodeEt.setText(code);  //输入框
                                mGetSMSCode=true;
                        }
                });
                registerReceiver(mReceiver, filter);
               
        }
        
        /**
     * 注销短信监听器
     */
        private void unRegisterSMSReceiver() {
                if (mReceiver != null) {
                        IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
                        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);// 设置优先级最大
                        registerReceiver(mReceiver, filter);  //PS。有可能短信会延迟,然后点多几次下发短信时候,
当已经有短信后,会注销掉广播,但是同时的短信下发会产生注销多次。会出现unregisterReceiver(mReceiver)这个地方报错,所以重新注册,再注销。还希望高手能够简化
                        unregisterReceiver(mReceiver);
                }
        }

当然啦,配置文件也要加响应的权限如读取短信<uses-permission android:name="android.permission.READ_SMS"/>

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

原创粉丝点击