Android獲取和讀取短信驗證碼的實現(xiàn)方法
現(xiàn)如今,驗證碼在Android的客戶端還是非常普遍的.通過手機賬號和驗證碼直接去注冊應(yīng)用賬戶的信息.很多應(yīng)用都以這種方式來完成注冊.簡單的介紹一下吧.
Android獲取短信驗證碼還是比較簡單的,通過Mob官網(wǎng)提供的ShareSDK,調(diào)用其中內(nèi)部的方法,就可以獲取到短信的驗證碼了.提供一下Mob的官網(wǎng)地址.http://www.mob.com/#/在官網(wǎng)上注冊相關(guān)的信息之后,下載相關(guān)的jar包和.so文件就可以實現(xiàn)獲取短信驗證碼了(2.0之前的版本都需要下載jar包和 .so文件,而現(xiàn)在的2.2版本已經(jīng)不需要下載.so文件了,通過加載SMSSDK.jar,MobCommons.jar,MobTools.jar包就可以直接使用).如何注冊我就不解釋了.
最后注冊完的樣式就是這樣的..我們來看看具體實現(xiàn)..
1.如何獲取短信驗證碼.
i.首先需要初始化SDK,第三方這些東西首先必須要有的操作就是初始化SDK.一般都在OnCreate()函數(shù)中來完成.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 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); }
這個是必須要進行的操作,否則后續(xù)的東西都將無法完成.initSDK(Context context,String AppKey,String AppSECRET),初始化需要傳遞Context對象,以及我們申請的Key和SECRET.并且這里定義了一個EventHandler,用來進行驗證的時候?qū)⒁恍┫⑻峁┙o主線程的Handler,讓主線程來做一些相關(guān)的操作來通知用戶驗證的情況到底如何.
ii.調(diào)用SMSSDK.getVerificationCode(String,String)方法
初始化SDK之后,我們就可以通過使用getVerificationCode()方法來獲取我們的驗證碼了.
/** * @param string 電話號碼的區(qū)號 比如說86 * @param string 具體的電話號碼 */ SMSSDK.getVerificationCode("86", PhoneEd.getText().toString());
我們在調(diào)用方法的時候,需要傳遞我們手機號碼的區(qū)號和具體的手機號碼.由于中國國內(nèi)是86開頭.因此傳遞的區(qū)號就是86,在加上自己的電話號碼就可以通過網(wǎng)絡(luò)調(diào)用方法來獲取相關(guān)的驗證碼了.
iii.驗證我們輸入的驗證碼和發(fā)送過來的驗證碼是一致的.
當(dāng)驗證碼發(fā)送過來的時候,客戶端一般就需要進行輸入,但是這里需要一個驗證的過程,判斷當(dāng)前用戶輸入的驗證碼和發(fā)送過來的驗證碼是否一致.
SMSSDK.submitVerificationCode("86", phone, CodeEd.getText().toString());
驗證的方式通過調(diào)用submitVerificationCode()方法來完成.需要傳遞區(qū)號,電話號碼,以及我們輸入的驗證碼的數(shù)值.驗證的過程由ShareSDK幫我們完成.因此就不需要執(zhí)行太多復(fù)雜的操作.當(dāng)我們傳遞的數(shù)值和發(fā)送過來的數(shù)值是一樣的,那么就會驗證成功,否則就會驗證失敗.
這樣在我們的客戶端軟件上就可以通過這種驗證方式來完成注冊功能.當(dāng)驗證成功后,就可以進入新的界面,如果驗證失敗,那么就需要確認(rèn)輸入的驗證碼.這樣就能夠完成應(yīng)用程序的驗證碼驗證.
一般情況下,我們只需要通過查看短信,然后提交相關(guān)的驗證碼就可以了,但是還有一些其他的應(yīng)用更加的人性化,當(dāng)驗證碼信息發(fā)送到手機內(nèi)部的時候直接就能夠獲取到相關(guān)的驗證碼,然后直接添加在需要驗證的地方,這樣非常的方便,并且還能防止用戶輸入錯誤.那么這就涉及到讀取短信的相關(guān)內(nèi)容了.
iv.添加相關(guān)的權(quán)限
<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" />
那么如何獲取短信的相關(guān)內(nèi)容呢?
2.如何獲取剛收到的短信的相關(guān)內(nèi)容.
一般而言,短信的驗證是以新短信的方式直接發(fā)送給用戶的,那么應(yīng)用程序如果想到讀取剛收到的短息內(nèi)容,就需要有相關(guān)的監(jiān)聽事件.我通過使用ContentObserver來實現(xiàn)的.通過使用這個類可以捕捉特定的uri使數(shù)據(jù)庫改變,然后進而作一些相關(guān)的處理.
那么我們就可以這樣去實現(xiàn),通過繼承ContentObserver類,重寫內(nèi)部的onChange方法,設(shè)置特定的Uri,使得我們的類能夠監(jiān)聽短信數(shù)據(jù)發(fā)生了變化這樣我們的應(yīng)用程序就知道什么時候短信到來了.那么短信到來之后,我們通過對短信內(nèi)容的獲取,然后讀取內(nèi)容中的驗證碼信息就可以了.
private class SmsObserver extends ContentObserver { public SmsObserver(Handler handler) { super(handler); // TODO Auto-generated constructor stub } /** *Uri.parse("content://sms/inbox")表示對收到的短信的一個監(jiān)聽的uri. */ @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub StringBuilder sb = new StringBuilder(); Cursor cursor = getContentResolver().query( Uri.parse("content://sms/inbox"), null, null, null, null); //這里不要使用while循環(huán).我們只需要獲取當(dāng)前發(fā)送過來的短信數(shù)據(jù)就可以了. cursor.moveToNext(); sb.append("body=" + cursor.getString(cursor.getColumnIndex("body"))); //獲取短信內(nèi)容的實體數(shù)據(jù). Pattern pattern = Pattern.compile("[^0-9]"); //正則表達式. Matcher matcher = pattern.matcher(sb.toString()); CodeText = matcher.replaceAll(""); CodeEd.setText(CodeText); //將輸入驗證碼的控件內(nèi)容進行改變. cursor.close(); //關(guān)閉游標(biāo)指針. super.onChange(selfChange); } }
實現(xiàn)類的方式如上,通過重寫OnChange方法來進行后續(xù)的操作,這里的cursor可以對當(dāng)前的短信數(shù)據(jù)庫中的數(shù)據(jù)進行查找,這里的cursor指針不要使用while循環(huán),因為驗證碼這條短信是隨發(fā)即用的,我們也只需要獲取當(dāng)前發(fā)送過來的驗證碼短信中的相關(guān)內(nèi)容,如果cursor使用了while循環(huán),那么將會讀取短信中的所有內(nèi)容.這并不是我們想要的.
當(dāng)我們獲取到了短信的具體內(nèi)容之后,我們可以通過使用正則表達式,去匹配短信內(nèi)容的數(shù)字,然后就能夠獲取到驗證碼數(shù)據(jù)了.大體的思路就是這樣一個情況.同時我們需要添加相關(guān)用戶權(quán)限.
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" />
完成了上面的步驟之后,我們需要獲取ContentResolver實例,然后注冊ContentObserver。
getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new SmsObserver(new Handler()));
注冊我們需要傳遞相關(guān)的uri,第二個參數(shù)決定匹配uri的方式,如果設(shè)置為true的話,那么表示不精確匹配,那么也就表示,如果是一類的uri,那么都會被匹配到,如果設(shè)置為false,那么也就只能匹配到我們傳遞進去的uri,也就是所謂的精確匹配.最后一個對象需要傳遞一個子類的實例,并且需要傳遞Handler對象.這樣我們也就可以在這個方法里去更新ui了.
當(dāng)我們不需要使用ContentObserver的時候,我們只需要注銷注冊就可以了.
相對而言,驗證碼信息一般都是內(nèi)容比較少的,如果內(nèi)容比較復(fù)雜,然后還有其他額外的數(shù)字信息,那么我們在使用正則表達式的時候同時需要進行相關(guān)的優(yōu)化.
最后上一個源代碼:
package com.example.sms; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.json.JSONObject; import cn.smssdk.EventHandler; import cn.smssdk.SMSSDK; import cn.smssdk.utils.SMSLog; import android.app.Activity; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; 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; public class MainActivity extends Activity implements OnClickListener { private Button getCode; private Button Identity; private EditText PhoneEd; private EditText CodeEd; private String AppKey = "110ee66f30b40"; private String APPSECRET = "85ec67aed1b89e3ec73f37b8b89f5142"; public String phone; private String CodeText; private 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; if (result == SMSSDK.RESULT_COMPLETE) { if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) { Toast.makeText(getApplicationContext(), "提交驗證碼成功", Toast.LENGTH_SHORT).show(); } else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) { // 已經(jīng)驗證 Toast.makeText(getApplicationContext(), "驗證碼已經(jīng)發(fā)送", Toast.LENGTH_SHORT).show(); } } else { int status = 0; try { ((Throwable) data).printStackTrace(); Throwable throwable = (Throwable) data; JSONObject object = new JSONObject(throwable.getMessage()); String des = object.optString("detail"); status = object.optInt("status"); if (!TextUtils.isEmpty(des)) { Toast.makeText(MainActivity.this, des, Toast.LENGTH_SHORT).show(); return; } } catch (Exception e) { SMSLog.getInstance().w(e); } } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 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() { getCode = (Button) findViewById(R.id.getCode); Identity = (Button) findViewById(R.id.Indentity); PhoneEd = (EditText) findViewById(R.id.PhoneEd); CodeEd = (EditText) findViewById(R.id.Code); getCode.setOnClickListener(this); Identity.setOnClickListener(this); } private class SmsObserver extends ContentObserver { public SmsObserver(Handler handler) { super(handler); // TODO Auto-generated constructor stub } @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub StringBuilder sb = new StringBuilder(); Cursor cursor = getContentResolver().query( Uri.parse("content://sms/inbox"), null, null, null, null); cursor.moveToNext(); sb.append("body=" + cursor.getString(cursor.getColumnIndex("body"))); System.out.println(sb.toString()); Pattern pattern = Pattern.compile("[^0-9]"); Matcher matcher = pattern.matcher(sb.toString()); CodeText = matcher.replaceAll(""); CodeEd.setText(CodeText); cursor.close(); super.onChange(selfChange); } } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.getCode: // 獲取驗證碼的過程. if (!TextUtils.isEmpty(PhoneEd.getText().toString())) { getContentResolver().registerContentObserver( Uri.parse("content://sms"), true, new SmsObserver(new Handler())); SMSSDK.getVerificationCode("86", PhoneEd.getText().toString()); phone = PhoneEd.getText().toString(); } else { Toast.makeText(MainActivity.this, "電話號碼不能為空", Toast.LENGTH_LONG) .show(); } break; case R.id.Indentity: SMSSDK.submitVerificationCode("86", phone, CodeEd.getText() .toString()); break; } } protected void onDestroy() { SMSSDK.unregisterAllEventHandler(); getContentResolver().unregisterContentObserver(new SmsObserver(handler)); }; }
這樣就能夠完成一個簡單的通過使用短信驗證碼的方式來實現(xiàn)驗證,在一般的項目中,我們可以根據(jù)具體的需求進行相關(guān)的改良,總之萬變不離其宗思路基本都是一樣的.當(dāng)然在判斷是否有短信到來也可以使用BroadCaseReceiver來實現(xiàn),不過我看了網(wǎng)上的一些相關(guān)的資源,自己也試了一下,沒有實現(xiàn)出來.感覺沒有ContentObserver這么簡單方便.
源碼下載:Android獲取和讀取短信驗證碼
以上就是Android獲取和讀取短信驗證碼的實現(xiàn)方法,希望對大家學(xué)習(xí)Android軟件編程有所幫助。
相關(guān)文章
基于barcodescanner實現(xiàn)Android二維碼掃描功能
這篇文章主要為大家詳細(xì)介紹了基于barcodescanner實現(xiàn)Android二維碼掃描功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07Android使用多線程進行網(wǎng)絡(luò)聊天室通信
這篇文章主要為大家詳細(xì)介紹了Android使用多線程進行網(wǎng)絡(luò)聊天室通信,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10Android隨手筆記44之JSON數(shù)據(jù)解析
本文將主要介紹在Android開發(fā)中,如何在服務(wù)器端創(chuàng)建JSON數(shù)據(jù),以及如何在Android客戶端對JSON數(shù)據(jù)進行解析,對android json解析 相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧2015-12-12android開發(fā)教程之實現(xiàn)listview下拉刷新和上拉刷新效果
這篇文章主要介紹了android實現(xiàn)listview下拉刷新和上拉刷新效果,Android的ListView上拉下拉刷新,原理都一樣,在Touch事件中操作header/footer的paddingTop屬性,需要的朋友可以參考下2014-02-02AndroidStudio中重載方法@Override的使用詳解
這篇文章主要介紹了AndroidStudio中重載方法@Override的使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04- 事件是一種有用來收集用戶與應(yīng)用程序互動數(shù)據(jù)的互動組件,如按鍵或觸摸屏等放置事件,因為每個事件從Android框架維護事件隊列先入先出(FIFO)基礎(chǔ)上的隊列??梢栽诔绦蛑胁东@這些事件,按要求并采取適當(dāng)?shù)膭幼?/div> 2023-02-02
解決video標(biāo)簽在安卓webview下無法自動播放問題
這篇文章主要介紹了video標(biāo)簽在安卓webview下無法自動播放問題的解決方法 ,需要的朋友可以參考下2014-03-03ViewPager+Fragment實現(xiàn)側(cè)滑導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了ViewPager+Fragment實現(xiàn)側(cè)滑導(dǎo)航欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05最新評論