当我们需要在Android机器上实现自动获取短信验证码功能时,首先我们需要设置相关权限,即在AndroidManifest中设置
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" />
当Android版本是 6.0或更高版本时,权限需要动态获取,运行时弹出请求提示,经用户同意后才能获得相应权限;
// 定义要申请的权限 private String[] permissions = {Manifest.permission.READ_SMS}; // 定义requestCode private final int RCode = 10086; // 在Activity的onCreate方法中进行版本判断。当手机系统大于等于 23 时,才有必要去判断权限是否获取 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 检查该权限是否已经获取 int i = checkSelfPermission(permissions[0]); // 权限是否已经 授权 GRANTED---授权 DINIED---拒绝 if (i != PackageManager.PERMISSION_GRANTED) { // 如果没有授予该权限,就去提示用户请求 requestPermissions(permissions, RCode); }else{ //权限已经授权,直接注册短信验证码识别功能 registAutoMsg(); } }else{ //手机系统小于23时,不需要动态获取权限,直接注册短信验证码识别功能 registAutoMsg(); }
// 重写用户权限申请的回调方法 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); //根据requestCode 进行权限回调处理 if (requestCode == RCode) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "权限获取成功", Toast.LENGTH_SHORT).show(); //用户同意授权,注册短信验证码识别功能 registAutoMsg(); } } } }
//定义短信识别回调 private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 1) { String code = (String)msg.obj; //定义JniHelper,与cocos C++ 代码进行交互,把获取的短信验证码发送给cocos JniHelper.SendCode(code); } } };
//注册自动识别短信验证码功能 private void registAutoMsg(){ SmsObserver mSmsObeserver = new SmsObserver(this, mHandler); Uri smsUri = Uri.parse("content://sms"); getContentResolver().registerContentObserver(smsUri, true, mSmsObeserver); }
定义JniHelper类,与cocos C++ 代码进行交互,把短信验证码发送给cocos
package org.cocos2dx.cpp; public class JniHelper { public static native void SendCode(String code); }
接下来定义SmsObserver类,识别短信验证码功能
package org.cocos2dx.cpp; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.annotation.SuppressLint; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.os.Message; import android.util.Log; public class SmsObserver extends ContentObserver { private final String TAG = "wwz"; private Context mContext; private Handler mHandler;//更新ui public SmsObserver(Context context, Handler handler) { super(handler); mContext = context; mHandler = handler; } @SuppressLint("NewApi") @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); /* 收到一条短信,onChange()会执行两次,uri不同 */ if (uri.toString().equals("content://sms/raw")) {//未写入数据库,不进行任何操作 return; } else {//此时已经写入数据库 Uri inboxUri = Uri.parse("content://sms/inbox"); /* 按照日期倒序排序 */ Cursor cursor = mContext.getContentResolver().query(inboxUri, null, null, null, "date desc"); if (cursor != null) { if (cursor.moveToFirst()) {//游标移动到first位置 /* 发件人的号码 */ String address = cursor.getString(cursor.getColumnIndex("address")); /* 短信内容 */ String body = cursor.getString(cursor.getColumnIndex("body")); Log.i(TAG, "address:" + address + ",body:" + body); /* 利用正则提取验证码(根据实际情况修改) */ Pattern pattern = Pattern.compile("(\\d{6})");//提取六位数字 Matcher matcher = pattern.matcher(body);//进行匹配 if(matcher.find()){//匹配成功 String code = matcher.group(0); Message msg = mHandler.obtainMessage(1, code); mHandler.sendMessage(msg); Log.i(TAG,"code:"+code); } } cursor.close(); } } } }