Android实时监听并获取短信内容的两种方法

通过访问短信内容提供器可以获取手机内已存在的所有短信,但是有时候需要获取的只是刚接收到的第一条短信,比如登录账号时需要手机验证码,这就需要实时监听手机短信。

监听手机短信的到来有两种方法:

(1)通过广播接收器:当手机收到一条短信时系统会发送一条广播:"android.provider.Telephony.SMS_RECEIVED",通过该广播就能够知道是否有新短信,通过该广播还可以获取到短信内容。

(2)通过观察短信数据库:当手机收到一条短信时,短信数据库会发生变化。Android提供了ContentObserver类,只要创建一个类继承自ContentObserver类,并重写类里的onChange()方法,当短信数据库发生变化时,就会回调到onChange()方法。

具体代码:

方法一:广播接收器:

public class MainActivity extends AppCompatActivity {

    IntentFilter filter;
    SmsReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        filter=new IntentFilter();
        filter.addAction("android.provider.Telephony.SMS_RECEIVED" );
        receiver=new SmsReceiver();
        registerReceiver(receiver,filter);//注册广播接收器
    }


    public class SmsReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            StringBuilder content = new StringBuilder();//用于存储短信内容
            String sender = null;//存储短信发送方手机号
            Bundle bundle = intent.getExtras();//通过getExtras()方法获取短信内容
            String format = intent.getStringExtra("format");
            if (bundle != null) {
                Object[] pdus = (Object[]) bundle.get("pdus");//根据pdus关键字获取短信字节数组,数组内的每个元素都是一条短信
                for (Object object : pdus) {
                   SmsMessage message=SmsMessage.createFromPdu((byte[])object,format);//将字节数组转化为Message对象
                   sender = message.getOriginatingAddress();//获取短信手机号
                   content.append(message.getMessageBody());//获取短信内容
                }
            }
        }
    }

    @Override
    protected  void onDestroy(){
        unregisterReceiver(receiver);//解绑广播接收器
    }
}

    

分析:首先在onCreate()方法内注册广播接收器SmsReceiver,当接收到"android.provider.Telephony.SMS_RECEIVED"广播之后,就会回调到广播接收器内的onReceive()方法。在onReceive()方法内通过intent的getExtras()方法获取到一个Bundle实例,再通过关键词“pdus”从Bundle实例中获取到短信字节数组—pdus。最后通过循环调用SmsMessage的createFromPdu()方法将字节数组转化为SmsMessage对象,通过SmsMessage对象就可以获取到短信的内容了。

方法二:短信数据库

public class MainActivity extends AppCompatActivity {

    
    private SmsObserver smsObserver;
    private final Handler smsHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        smsObserver = new SmsObserver(smsHandler);
        getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, smsObserver);
        
    }


    class SmsObserver extends ContentObserver{
        private Uri uri;
        public SmsObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange,Uri uri) {
            super.onChange(selfChange);
            if(uri.toString().equals("content://sms/raw")){
                return;
            }
            ...//读取短信操作
        }
        
}

分析:代码中创建了一个SmsObserver类继承自ContentObserver类,并重写了onChange()方法,在onChange()方法内进行读取手机短信操作。在onCreate()方法内创建了一个SmsObserver实例,并注册到“content://sms/”上,只要有短信到来就会触发SmsObserver实例的onChange()方法。

注:onChange()方法有时候会被调用两次:当收到短信时调用一次,当短信显示到屏幕上时又调用一次,所以需要return掉一次调用,当uri为:“content://sms/raw”时return掉。

你可能感兴趣的:(Android小程序)