Android短信驗證與內容監聽識別

最近做一個用戶註冊短信驗證的功能,爲了方便用戶我就增加一個自動識別驗證短信的功能。下面直接上代碼:

<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、下面實現短信內容識別Service
package 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不要忘了聲明,因爲項目中的部分代碼,所以現在還沒有源碼,以後有時間會整理出來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章