最近做一個用戶註冊短信驗證的功能,爲了方便用戶我就增加一個自動識別驗證短信的功能。下面直接上代碼:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.gesoft.qingchunhao"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
style="@style/layout_direct_vertical"
android:layout_weight="11"
android:layout_margin="10dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="手機號:" />
<EditText
android:id="@+id/et_phone"
style="@style/layout_direct_horizontal"
android:layout_weight="2"
android:inputType="number"
android:ems="10" >
</EditText>
<EditText
android:id="@+id/et_code"
style="@style/layout_direct_horizontal"
android:layout_weight="1"
android:inputType="number"
android:hint="驗證碼"
android:ems="10" />
<Button
android:id="@+id/btn_validation"
android:layout_width="50dp"
android:layout_height="match_parent"
android:background="@drawable/huoqu"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"
android:text="獲取" />
</LinearLayout>
</LinearLayout>
2、使用代碼實現短信驗證,這裏使用的是Mob短信驗證平臺,詳細內容參考:http://blog.csdn.net/crazy1235/article/details/41912003。
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import cn.smssdk.EventHandler;
import cn.smssdk.SMSSDK;
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class RegisteredActivity extends Activity implements OnClickListener{
private EditText etPhone;
private EditText etCode;
private Button btnValidation;
private int i = 30;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.registered);
initView();
initData();
setListener();
}
private void initView() {
// TODO Auto-generated method stub
etPhone = (EditText) findViewById(R.id.et_phone);
etCode = (EditText) findViewById(R.id.et_code);
btnValidation = (Button) findViewById(R.id.btn_validation);
}
private void initData() {
// TODO Auto-generated method stub
// 啓動短信驗證sdk
SMSSDK.initSDK(this, "61cbcec26abd", "1b4f765b20660bf975f942c1d71cc64e");
EventHandler eventHandler = new EventHandler(){
@Override
public void afterEvent(int event, int result, Object data) {
Message msg = new Message();
msg.what = 1;
msg.arg1 = event;
msg.arg2 = result;
msg.obj = data;
handler.sendMessage(msg);
}
};
//註冊回調監聽接口
SMSSDK.registerEventHandler(eventHandler);
}
private void setListener() {
// TODO Auto-generated method stub
btnValidation.setOnClickListener(this);
}
private void smsMonitor(){
//註冊廣播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.gesoft.qingchunhao.activity.registered");
registerReceiver(broadcastReceiver, intentFilter);
//啓動短信監聽Service
intent = new Intent(RegisteredActivity.this, SmsStatusService.class);
startService(intent);
}
private void stopSmsMonitor(){
//註銷廣播,停止Service
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
etCode.setText(intent.getStringExtra("code"));
}
};
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String phoneNums = etPhone.getText().toString();
switch (v.getId()) {
case R.id.btn_validation:
// 1. 通過規則判斷手機號
if (!judgePhoneNums(phoneNums)) {
return;
}
smsMonitor();
// 2. 通過sdk發送短信驗證
SMSSDK.getVerificationCode("86", phoneNums);
// 3. 把按鈕變成不可點擊,並且顯示倒計時(正在獲取)
i = 30;
btnValidation.setClickable(false);
btnValidation.setText("(" + i + ")");
new Thread(new Runnable() {
@Override
public void run() {
for (; i > 0; i--) {
handler.sendEmptyMessage(2);
if (i <= 0) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
handler.sendEmptyMessage(3);
}
}).start();
break;
}
}
/**
* 判斷手機號碼是否合理
* @param phoneNums
*/
private boolean judgePhoneNums(String phoneNums) {
if (isMatchLength(phoneNums, 11)
&& isMobileNO(phoneNums)) {
return true;
}
Toast.makeText(this, "手機號碼輸入有誤!",Toast.LENGTH_SHORT).show();
return false;
}
/**
* 判斷一個字符串的位數
* @param str
* @param length
* @return
*/
public static boolean isMatchLength(String str, int length) {
if (str.isEmpty()) {
return false;
} else {
return str.length() == length ? true : false;
}
}
/**
* 驗證手機格式
*/
public static boolean isMobileNO(String mobileNums) {
/*
* 移動:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
* 聯通:130、131、132、152、155、156、185、186 電信:133、153、180、189、(1349衛通)
* 總結起來就是第一位必定爲1,第二位必定爲3或5或8,其他位置的可以爲0-9
*/
String telRegex = "[1][358]\\d{9}";// "[1]"代表第1位爲數字1,"[358]"代表第二位可以爲3、5、8中的一個,"\\d{9}"代表後面是可以是0~9的數字,有9位。
if (TextUtils.isEmpty(mobileNums))
return false;
else
return mobileNums.matches(telRegex);
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
String sign = (String)msg.obj;
SimpleHUD.dismiss();
if(!TextUtils.isEmpty(sign) && sign.equals("註冊成功!")){
SimpleHUD.showSuccessMessage(RegisteredActivity.this, sign);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
finish();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}else{
SimpleHUD.showErrorMessage(RegisteredActivity.this, sign);
}
break;
case 1:
SimpleHUD.dismiss();
int event = msg.arg1;
int result = msg.arg2;
Object data = msg.obj;
if (result == SMSSDK.RESULT_COMPLETE) {
// 短信註冊成功後,返回MainActivity,然後提示
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
Toast.makeText(getApplicationContext(), "驗證成功",Toast.LENGTH_SHORT).show();
} else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) {
Toast.makeText(getApplicationContext(), "驗證碼已經發送",Toast.LENGTH_SHORT).show();
} else {
((Throwable) data).printStackTrace();
}
}else{
SimpleHUD.showErrorMessage(RegisteredActivity.this, "驗證碼錯誤!");
}
break;
case 2:
btnValidation.setText("(" + i + ")");
break;
case 3:
btnValidation.setText("獲取");
btnValidation.setClickable(true);
break;
}
}
};
@Override
protected void onDestroy() {
SMSSDK.unregisterAllEventHandler();
stopSmsMonitor();
super.onDestroy();
}
}
上面還缺少一個驗證按鈕,進行驗證。增加一個按鈕,點擊事件中加入下面的方法進行驗證。SMSSDK.submitVerificationCode("86", phoneNums, etCode.getText().toString());
3、下面實現短信內容識別Servicepackage com.gesoft.qingchunhao.activity.registered;
import android.app.Service;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
public class SmsStatusService extends Service{
@Override
public void onCreate() {
//爲content://sms的數據改變註冊監聽器
getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, new SmsObserver(new Handler()));
super.onCreate();
}
// ContentObserver監聽器類
private final class SmsObserver extends ContentObserver{
public SmsObserver(Handler handler){
super(handler);
}
public void onChange(boolean selfChange){
sendMsg();
}
private void sendMsg(){
Cursor cursor = getContentResolver().query(Uri.parse("content://sms/"), null, null, null, null);
if (cursor.moveToFirst()){
String strMsm = cursor.getString(cursor.getColumnIndex("body"));
if(strMsm.indexOf("短信中的關鍵字") != -1){
Intent intent = new Intent();
//截取驗證碼,一般爲後四位
intent.putExtra("code", strMsm.substring(strMsm.length()-4));
//爲了過濾廣播設置Action,唯一的
intent.setAction("com.gesoft.qingchunhao.activity.registered");
sendBroadcast(intent);
}
}
if(cursor!=null){
cursor.close();
cursor=null;
}
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
4、短信監聽需要的權限<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
還有Service不要忘了聲明,因爲項目中的部分代碼,所以現在還沒有源碼,以後有時間會整理出來。