Android 短信验证码自动填入

Android 短信验证码自动填入

下载地址:https://download.csdn.net/download/qq_31939617/11367198

MainActivity .class

package com.ryan.smscontentobsever;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    public static final int SMS_CODE = 1;
    public static final int READ_SMS_PERMISSION = 2;

    private EditText mSmsCode;
    private SMSContentObserver smsContentObserver;

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SMS_CODE:
                    mSmsCode.setText(msg.obj.toString());
                    break;
                default:
                    break;
            }

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSmsCode = (EditText) findViewById(R.id.smsCode);
        checkPermissionsAndRegisterObserver(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //注销smsContentObserver
        getContentResolver().unregisterContentObserver(smsContentObserver);
    }

    /**
     * 注册SmsContentObserver
     * <p>
     * 为什么注册的时候使用的URI是"content://sms/",而直接是"content://sms/inbox"?
     * 通过测试发现只能监听此Uri “content://sms/”
     * 而不能监听其他的Uri,比如"content://sms/inbox"等
     */
    private void registerSmsContentObserver() {
        smsContentObserver = new SMSContentObserver(this, mHandler);
        getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, smsContentObserver);
    }

    /**
     * 检测是否有赋予READ_SMS权限,
     * 若有则注册SmsContentObserver
     * 若没有则提醒用户授权
     *
     * @param context
     */
    private void checkPermissionsAndRegisterObserver(Context context) {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, READ_SMS_PERMISSION);
        } else {
            registerSmsContentObserver();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case READ_SMS_PERMISSION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    registerSmsContentObserver();
                } else {
                    Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }
}

SMSContentObserver .class

package com.ryan.smscontentobsever;

import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.ryan.smscontentobsever.MainActivity.SMS_CODE;

/**
 * 短信验证码截取
 */
public class SMSContentObserver extends ContentObserver {

    private static final String TAG = "SMSContentObserver";

    private Context mContext;   //上下文
    private Handler mHandler;   //更新UI线程
    private String code;        //验证码

    public SMSContentObserver(Context context, Handler handler) {
        super(handler);
        mContext = context;
        mHandler = handler;
    }

    /**
     * 回调函数, 当所监听的Uri发生改变时,就会回调此方法
     * <p>
     * 注意当收到短信的时候会回调两次
     *
     * @param selfChange 此值意义不大 一般情况下该回调值false
     * @param uri
     */
    @Override
    public void onChange(boolean selfChange, Uri uri) {
        super.onChange(selfChange, uri);
        Log.e(TAG, uri.toString());

        // 第一次回调 不是我们想要的 直接返回
        if (uri.toString().equals("content://sms/raw")) {
            return;
        }

        // 第二次回调 查询收件箱里的内容
        Uri inboxUri = Uri.parse("content://sms/inbox");

        // 按时间顺序排序短信数据库
        Cursor c = mContext.getContentResolver().query(inboxUri, null, null,
                null, "date desc");

        if (c != null) {
            if (c.moveToFirst()) {
                // 获取手机号
                String address = c.getString(c.getColumnIndex("address"));
                // 获取短信内容
                String body = c.getString(c.getColumnIndex("body"));

                Log.e(TAG, "onChange: -----------------------" + address + "---" + body);

                // 判断手机号是否为目标号码
//                if (!address.equals("你的目标号码"))
//                {
//                    return;
//                }

                // 正则表达式截取短信中的6位验证码
                //这个地方要特别注意,如果你的验证码不是6位数字,就不会自动填入,需要处理一下
                Pattern pattern = Pattern.compile("(\\d{6})");
                Matcher matcher = pattern.matcher(body);

                // 如果找到通过Handler发送给主线程
                if (matcher.find()) {
                    code = matcher.group(0);
                    mHandler.obtainMessage(SMS_CODE, code).sendToTarget();
                }
            }
        }
        c.close();
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="50dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="您的验证码为:" />

    <EditText
        android:id="@+id/smsCode"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
   <uses-permission android:name="android.permission.READ_SMS" />

下载地址:https://download.csdn.net/download/qq_31939617/11367198

发布了184 篇原创文章 · 获赞 70 · 访问量 37万+

猜你喜欢

转载自blog.csdn.net/qq_31939617/article/details/96139324