天天看點

Android擷取短信驗證碼

  Android開發中關于短息驗證碼的設計層出不窮,越來越多的應用為了更好的提高軟體的安全性,開始使用通過伺服器向使用者發送驗證碼的方式,來保護使用者個人資訊的安全性。無論是使用者注冊時的資訊驗證還是當使用者發出找回密碼請求時的短信驗證,他們的工作原理大緻上是一緻的,因為項目的需要研究了一下關于這方面的知識,本篇我将帶領大家一起實作這一當下流行的設計方案。

  衆所周知,短信驗證需要伺服器端生成一個驗證碼,然後發送到使用者輸入的手機上,這個過程需要伺服器主動向客戶發送驗證短信,是以這是就需要一個移動或聯通的發送短息接口,由于本人目前尚處于學生階段,沒有獲得這個接口的權限,是以我就選擇了借助網上的移動開發服務平台,來完成這個功能的實作,這裡我借用的平台是:http://dashboard.mob.com/,大家可以關注一下,這個平台為我們開發移動應用提供了很好的技術指導,可以大大縮短我們的開發周期。廢話不多說,下面開始我們今天的重點。

  官方為我們提供了兩種設計方式:第一種調用内部GUI實作;另一種通過自定義GUI實作,對于第一種方式,我就不再多講,因為官方文檔提供了很詳細的實行步驟,大家隻需要按照上面的步驟去實作即可,沒有難度。本篇我将帶領大家通過自定義GUI實作短信驗證功能。首先開發之前你可以先查閱一下官方提供的無GUI  API,然後下載下傳一下官方提供的dome,做好這些工作之後,我們就可以開始我們的設計了。

  1、将demo中的libs下的SMSSDK-1.1.5.jar和armeabi檔案夾拷貝到我們項目的libs目錄下,這是官方提供的類庫jar包。

  2、在AndroidManifest.xml檔案添權重限和聲明Action:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android_sms"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.android_sms.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity
            android:name="cn.smssdk.SMSSDKUIShell"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:windowSoftInputMode="stateHidden|adjustResize" />
        
    </application>

</manifest>      

  3、設計我們的布局檔案:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:text="短信驗證"
        android:textColor="#00ffaa"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView2"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:text="手機号:" />

    <EditText
        android:id="@+id/phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/textView1"
        android:layout_alignBottom="@+id/textView1"
        android:layout_toRightOf="@+id/textView1"
        android:maxLength="11"
        android:ems="11"
        android:inputType="phone" >
        <requestFocus />
        </EditText>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_marginTop="40dp"
        android:layout_below="@+id/phone"
        android:text="驗證碼:"/>

    <EditText
        android:id="@+id/cord"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_alignBaseline="@+id/textView3"
        android:layout_alignBottom="@+id/textView3"
        android:layout_alignLeft="@+id/phone"
        android:ems="4"
        android:maxLength="4"
        android:inputType="phone" />

    <Button
        android:id="@+id/getcord"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/cord"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="10dp"
        android:layout_toRightOf="@+id/cord"
        android:visibility="visible"
        android:text="擷取驗證碼" />

    <Button
        android:id="@+id/savecord"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/cord"
        android:layout_margin="20dp"
        android:text="驗證" />

    <TextView
        android:id="@+id/now"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/savecord"
        android:layout_toRightOf="@+id/cord"
        android:gravity="center_horizontal"
        android:visibility="gone"
        android:text="提示資訊"
        android:textColor="#aaaaaa" />
    
</RelativeLayout>      

  4、我們的MainActivity:

/**
 * 自定義GUI短信驗證
 * @time: 2015年7月4日
 */
public class MainActivity extends Activity implements OnClickListener{
    
    private EditText phone;
    private EditText cord;
    private TextView now;
    private Button getCord;
    private Button saveCord;
    
    private String iPhone;
    private String iCord;
    private int time = 60;
    private boolean flag = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        init();
        
     SMSSDK.initSDK(this, "<您的appkey>", "<您的appsecret>");
        EventHandler eh=new EventHandler(){

            @Override
            public void afterEvent(int event, int result, Object data) {
                
                Message msg = new Message();
                msg.arg1 = event;
                msg.arg2 = result;
                msg.obj = data;
                handler.sendMessage(msg);
            }
            
        };
        SMSSDK.registerEventHandler(eh);
        
    }

    private void init() {
        phone = (EditText) findViewById(R.id.phone);
        cord = (EditText) findViewById(R.id.cord);
        now = (TextView) findViewById(R.id.now);
        getCord = (Button) findViewById(R.id.getcord);
        saveCord = (Button) findViewById(R.id.savecord);
        getCord.setOnClickListener(this);
        saveCord.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.getcord:
            if(!TextUtils.isEmpty(phone.getText().toString().trim())){
                if(phone.getText().toString().trim().length()==11){
                    iPhone = phone.getText().toString().trim();
                    SMSSDK.getVerificationCode("86",iPhone);
                    cord.requestFocus();
                    getCord.setVisibility(View.GONE);
                }else{
                    Toast.makeText(MainActivity.this, "請輸入完整電話号碼", Toast.LENGTH_LONG).show();
                    phone.requestFocus();
                }
            }else{
                Toast.makeText(MainActivity.this, "請輸入您的電話号碼", Toast.LENGTH_LONG).show();
                phone.requestFocus();
            }
            break;

        case R.id.savecord:
            if(!TextUtils.isEmpty(cord.getText().toString().trim())){
                if(cord.getText().toString().trim().length()==4){
                    iCord = cord.getText().toString().trim();
                    SMSSDK.submitVerificationCode("86", iPhone, iCord);
                    flag = false;
                }else{
                    Toast.makeText(MainActivity.this, "請輸入完整驗證碼", Toast.LENGTH_LONG).show();
                    cord.requestFocus();
                }
            }else{
                Toast.makeText(MainActivity.this, "請輸入驗證碼", Toast.LENGTH_LONG).show();
                cord.requestFocus();
            }
            break;
            
        default:
            break;
        }
    }
    
    //驗證碼送成功後提示文字
    private void reminderText() {
        now.setVisibility(View.VISIBLE);
        handlerText.sendEmptyMessageDelayed(1, 1000);
    }

    Handler handlerText =new Handler(){
        public void handleMessage(Message msg) {
            if(msg.what==1){
                if(time>0){
                    now.setText("驗證碼已發送"+time+"秒");
                    time--;
                    handlerText.sendEmptyMessageDelayed(1, 1000);
                }else{
                    now.setText("提示資訊");
                    time = 60;
                    now.setVisibility(View.GONE);
                    getCord.setVisibility(View.VISIBLE);
                }
            }else{
                cord.setText("");
                now.setText("提示資訊");
                time = 60;
                now.setVisibility(View.GONE);
                getCord.setVisibility(View.VISIBLE);
            }
        };
    };
    
    Handler handler=new Handler(){

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            int event = msg.arg1;
            int result = msg.arg2;
            Object data = msg.obj;
            Log.e("event", "event="+event);
            if (result == SMSSDK.RESULT_COMPLETE) {
                //短信注冊成功後,傳回MainActivity,然後提示新好友
                if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {//送出驗證碼成功,驗證通過
                    Toast.makeText(getApplicationContext(), "驗證碼校驗成功", Toast.LENGTH_SHORT).show();
                    handlerText.sendEmptyMessage(2);
                } else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE){//伺服器驗證碼發送成功
                    reminderText();
                    Toast.makeText(getApplicationContext(), "驗證碼已經發送", Toast.LENGTH_SHORT).show();
                }else if (event ==SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES){//傳回支援發送驗證碼的國家清單
                    Toast.makeText(getApplicationContext(), "擷取國家清單成功", Toast.LENGTH_SHORT).show();
                }
            } else {
                if(flag){
                    getCord.setVisibility(View.VISIBLE);
                    Toast.makeText(MainActivity.this, "驗證碼擷取失敗,請重新擷取", Toast.LENGTH_SHORT).show();
                    phone.requestFocus();
                }else{
                    ((Throwable) data).printStackTrace();
                    int resId = getStringRes(MainActivity.this, "smssdk_network_error");
                    Toast.makeText(MainActivity.this, "驗證碼錯誤", Toast.LENGTH_SHORT).show();
                    cord.selectAll();
                    if (resId > 0) {
                        Toast.makeText(MainActivity.this, resId, Toast.LENGTH_SHORT).show();
                    }
                }
                
            }
            
        }
        
    };
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        SMSSDK.unregisterAllEventHandler();
    }

}      

  注:appkey和appsecret:在http://dashboard.mob.com/注冊一個賬号後,建立一個發送短信的應用,系統會自動為生成appkey和appsecret

    handlerText是我自定義設計的Handker對象,用于當伺服器發送驗證碼後,提醒使用者注意。

  最後附圖兩張,供大家參考:

  

Android擷取短信驗證碼

  

Android擷取短信驗證碼