在很多的應用當中,都涉及到了短信驗證的功能,比如在注冊或者找回密碼的時候,那么我們如何通過第三方的平台來完成這個功能呢?
本面博文就實現短信驗證,來做一個小的栗子。
第一步-下載開發包
首先你要在第三方平台mob擁有一個開發者賬號,這樣你才能使用其提供的短信驗證服務。
然后點擊下載相應開發平台的版本,我這里使用的是AS。
下載完畢后我們得到的是一個壓縮包,解壓縮,打開SMSSDK這個文件夾。
建議大家可以先看看HowToUse里面的內容:
第二步-將SDK導入到項目當中
官方的文檔說明,2.0.1開始使用aar文件集成。更方便快捷。所以這里建議各位將自己的AS升級到2.0.1的版本之上,這樣AS才能識別.aar后綴的文件。
把SMSSDK中的文件放在Module所在的Libs里面,如圖。
然后子啊該Module的build.gradle(上圖高亮的build.gradle,不是整個項目的build.gradle)當中添加依賴。
這樣一來,前期的准備工作就都結束了。接下來的工作就是去調用開發包中的各種方法。
第三步-啟動SDK
要想使用SDK提供的各種功能,首先就必須要啟動SDk。
首先我們要進入到剛才注冊過的mob官網,然后點擊【進入后台】
里面有mob的四個主要服務,【ShareSDK】、【SecurityCodeSDK】、【ShareREC】、【MobAPI】,我們要使用的【SecurityCodeSDK】。
接着,我們要創建一個應用。名稱就填寫我們剛才在AS中創建的項目名稱即可。
最關鍵的內容,就是你的App Key和App secret
把它們復制下來,放到AS當中。
接下來就可以啟動短信驗證的SDK了。
// 啟動短信驗證sdk SMSSDK.initSDK(this, appKey, appSecret);
第四部-注冊短信回調
這里為什么要注冊短信回調呢?我的理解是,這里的工作原理和廣播非常相似,我們在使用廣播的時候需要注冊一個廣播接收器,以便對不同的消息做出反義。
注冊的方法如下:
(1)定義一個EventHandler
private EventHandler eh;
(2)編寫EventHandler的事件處理
EventHandler即為操作回調。它包括4個方法,分別為:
public void onRegister(); public void beforeEvent(int event, Object data); public void afterEvent(int event, int result, Object data); public void onUnregister();
其中onRegister在回調對象注冊的時候被觸發。beforeEvent在操作執行前被觸發,其參數event表示操作的類型,data是從外部傳入的數據。afterEvent在操作結束時被觸發,同樣具備event和data參數,但是data是事件操作結果,其具體取值根據參數result而定。result是操作結果,為SMSSDK.RESULT_COMPLETE表示操作成功,為SMSSDK.RESULT_ERROR表示操作失敗。
更多詳細的內容,大家可以去看一下官網的這篇文章——Android 短信SDK操作回調
根據官方文檔提供的幾個Result值,我們對afterEvent中的收到的幾種消息做出處理,代碼如下:
eh=new EventHandler(){ @Override public void afterEvent(int event, int result, Object data) { if (result == SMSSDK.RESULT_COMPLETE) { //回調完成 if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) { //提交驗證碼成功 Message msg = new Message(); msg.arg1 = 0; msg.obj = data; handler.sendMessage(msg); Log.d(TAG, "提交驗證碼成功"); } else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) { Message msg = new Message(); //獲取驗證碼成功 msg.arg1 = 1; msg.obj = "獲取驗證碼成功"; handler.sendMessage(msg); Log.d(TAG, "獲取驗證碼成功"); } else if (event == SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES) { Message msg = new Message(); //返回支持發送驗證碼的國家列表 msg.arg1 = 2; msg.obj = "返回支持發送驗證碼的國家列表"; handler.sendMessage(msg); Log.d(TAG, "返回支持發送驗證碼的國家列表"); } } else { Message msg = new Message(); //返回支持發送驗證碼的國家列表 msg.arg1 = 3; msg.obj = "驗證失敗"; handler.sendMessage(msg); Log.d(TAG, "驗證失敗"); ((Throwable) data).printStackTrace(); } } };
由於EventHandler開啟了線程,所以不能直接在afterEvent中更新UI,所以還需要在MainActivity當中定義一個Handler來接受EventHandler發送過來的消息。
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.arg1) { case 0: //客戶端驗證成功,可以進行注冊,返回校驗的手機和國家代碼phone/country Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); break; case 1: //獲取驗證碼成功 Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); break; case 2: //返回支持發送驗證碼的國家列表 Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); break; } } };
完成上述操作之后,注冊短信回調
SMSSDK.registerEventHandler(eh); //注冊短信回調
- 1
- 1
第五部-完善UI
主界面布局如下
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/et_phone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="請輸入手機號" /> <Button android:id="@+id/bt_getCode" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="獲取驗證碼" /> <EditText android:id="@+id/et_code" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="輸入驗證碼"/> <Button android:id="@+id/bt_verify" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="驗證"/> </LinearLayout>
非常簡單,et_phone用於輸入手機號,bt_getCode獲取驗證碼,et_code用於輸入手機收到的驗證碼,bt_vertify對驗證碼進行驗證。
Java部分的代碼重點講下為按鈕bt_getCode和bt_vertify設置監聽事件。
bt_getCode.setClickable(false); bt_getCode.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //獲取驗證碼操作 phone=((EditText)findViewById(R.id.et_phone)).getText().toString(); if(phone.equals("")){ Toast.makeText(MainActivity.this,"手機號不能為空",Toast.LENGTH_SHORT).show(); }else{ //填寫了手機號碼,isMobileNO(phone)判斷號碼格式 if(isMobileNO(phone)){ //如果手機號碼無誤,則發送驗證請求 bt_getCode.setClickable(true); //讓按鈕的樣式變成60S倒計時 changeBtnGetCode(); //SMSSDK中自帶的2個方法 getSupportedCountries(); getVerificationCode("86", phone); }else{ //手機號格式有誤 Toast.makeText(MainActivity.this,"手機號格式錯誤,請檢查",Toast.LENGTH_SHORT).show(); } } } });
其中 changeBtnGetCode();的代碼為:
/* * 改變按鈕樣式 * */ private void changeBtnGetCode() { Thread thread = new Thread() { @Override public void run() { if (tag) { while (i > 0) { i--; //如果活動為空 if (MainActivity.this == null) { break; } MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { bt_getCode.setText("獲取驗證碼(" + i + ")"); bt_getCode.setClickable(false); } }); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } tag = false; } i = 60; tag = true; if (MainActivity.this != null) { MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { bt_getCode.setText("獲取驗證碼"); bt_getCode.setClickable(true); } }); } } }; thread.start(); }
isMobileNO()的代碼為:
private boolean isMobileNO(String phone) { /* 移動: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(phone)) return false; else return phone.matches(telRegex); } }
然后是 bt_vertify的監聽時間,比較簡單
bt_vertify.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //驗證操作 code=((EditText)findViewById(R.id.et_code)).getText().toString(); if (code.equals("")){ Toast.makeText(MainActivity.this,"驗證碼不能為空",Toast.LENGTH_SHORT).show(); }else{ //填寫了驗證碼,進行驗證,SMSSDK自帶的方法 submitVerificationCode("86", phone, code); } } });
最后別忘記在AndroidManifest.xml中添加網絡訪問的權限
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
附錄
效果圖
完整JAVA代碼
import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import cn.smssdk.EventHandler; import cn.smssdk.SMSSDK; import static cn.smssdk.SMSSDK.getSupportedCountries; import static cn.smssdk.SMSSDK.getVerificationCode; import static cn.smssdk.SMSSDK.submitVerificationCode; public class MainActivity extends AppCompatActivity { private final String TAG="--MainActivity--"; //app key和app secret 需要填自己應用的對應的!這里只是我自己創建的應用。 private final String appKey="1549a02f213cb"; private final String appSecret="5753971a3b122dd9caf36a23a59ba5d9"; private EventHandler eh; private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.arg1) { case 0: //客戶端驗證成功,可以進行注冊,返回校驗的手機和國家代碼phone/country Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); break; case 1: //獲取驗證碼成功 Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); break; case 2: //返回支持發送驗證碼的國家列表 Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); break; } } }; //View控件 private Button bt_getCode; private Button bt_vertify; //手機號碼 private String phone; //驗證碼 private String code; private boolean isChange; //控制按鈕樣式是否改變 private boolean tag = true; //每次驗證請求需要間隔60S private int i=60; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); // 啟動短信驗證sdk SMSSDK.initSDK(this, appKey, appSecret); eh=new EventHandler(){ @Override public void afterEvent(int event, int result, Object data) { if (result == SMSSDK.RESULT_COMPLETE) { //回調完成 if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) { //提交驗證碼成功 Message msg = new Message(); msg.arg1 = 0; msg.obj = data; handler.sendMessage(msg); Log.d(TAG, "提交驗證碼成功"); } else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) { Message msg = new Message(); //獲取驗證碼成功 msg.arg1 = 1; msg.obj = "獲取驗證碼成功"; handler.sendMessage(msg); Log.d(TAG, "獲取驗證碼成功"); } else if (event == SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES) { Message msg = new Message(); //返回支持發送驗證碼的國家列表 msg.arg1 = 2; msg.obj = "返回支持發送驗證碼的國家列表"; handler.sendMessage(msg); Log.d(TAG, "返回支持發送驗證碼的國家列表"); } } else { Message msg = new Message(); //返回支持發送驗證碼的國家列表 msg.arg1 = 3; msg.obj = "驗證失敗"; handler.sendMessage(msg); Log.d(TAG, "驗證失敗"); ((Throwable) data).printStackTrace(); } } }; SMSSDK.registerEventHandler(eh); //注冊短信回調 bt_getCode= (Button) findViewById(R.id.bt_getCode); bt_getCode.setClickable(false); bt_vertify= (Button) findViewById(R.id.bt_verify); bt_getCode.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //獲取驗證碼操作 phone=((EditText)findViewById(R.id.et_phone)).getText().toString(); if(phone.equals("")){ Toast.makeText(MainActivity.this,"手機號不能為空",Toast.LENGTH_SHORT).show(); }else{ //填寫了手機號碼 if(isMobileNO(phone)){ //如果手機號碼無誤,則發送驗證請求 bt_getCode.setClickable(true); changeBtnGetCode(); getSupportedCountries(); getVerificationCode("86", phone); }else{ //手機號格式有誤 Toast.makeText(MainActivity.this,"手機號格式錯誤,請檢查",Toast.LENGTH_SHORT).show(); } } } }); bt_vertify.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //驗證操作 code=((EditText)findViewById(R.id.et_code)).getText().toString(); if (code.equals("")){ Toast.makeText(MainActivity.this,"驗證碼不能為空",Toast.LENGTH_SHORT).show(); }else{ //填寫了驗證碼,進行驗證 submitVerificationCode("86", phone, code); } } }); } /* * 改變按鈕樣式 * */ private void changeBtnGetCode() { Thread thread = new Thread() { @Override public void run() { if (tag) { while (i > 0) { i--; //如果活動為空 if (MainActivity.this == null) { break; } MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { bt_getCode.setText("獲取驗證碼(" + i + ")"); bt_getCode.setClickable(false); } }); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } tag = false; } i = 60; tag = true; if (MainActivity.this != null) { MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { bt_getCode.setText("獲取驗證碼"); bt_getCode.setClickable(true); } }); } } }; thread.start(); } private boolean isMobileNO(String phone) { /* 移動: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(phone)) return false; else return phone.matches(telRegex); } }
源碼下載
項目地址:github
說明
1、為了方便大家的導入,這里附上我的AS的相關信息
大家可以根據自己的開發環境進行配置
2、這個栗子只是簡單的調用了SMSSDK的相關方法,在實際開發的過程中,需要結合項目的需求,活學活用