Android開發(fā)工程中集成mob短信驗(yàn)證碼功能的方法
一.前言
現(xiàn)在的app基本上都需要用到短信功能,注冊時(shí)或者有消息通知時(shí)需要給用戶發(fā)送一條短信,但是對(duì)于個(gè)人開發(fā)者來說,去買第三方的短信服務(wù)實(shí)在是有點(diǎn)奢侈,很好的是mob為我們提供了免費(fèi)的短信驗(yàn)證碼服務(wù)功能,我不是打廣告,的確覺得這項(xiàng)服務(wù)很不錯(cuò)。那么下面就簡單講一下如何在自己的工程里集成mob的短信功能,其實(shí)整個(gè)流程并不復(fù)雜,只是個(gè)人覺得mob的官方文檔有點(diǎn)小亂,官方Demo也有點(diǎn)小復(fù)雜,同時(shí)有一些細(xì)節(jié)地方容易被忽視,也會(huì)導(dǎo)致一些問題。
PS:太喜歡mob的logo了。

二.實(shí)現(xiàn)過程
本篇只涉及Android,如果是IOS系統(tǒng),還望自己斟酌,希望本篇文章也能給您提供幫助,同時(shí)IDE是Android Studio。
1.key申請(qǐng)
申請(qǐng)地址:http://www.mob.com,在產(chǎn)品中心選擇短信驗(yàn)證碼SDK,然后完成相應(yīng)的注冊和申請(qǐng)工作;
進(jìn)入自己的后臺(tái)中心,就可以看見自己的App Key和App Secret:

整體趨勢欄給我們展示了一些短信服務(wù)使用情況。未上線登記時(shí),我們可以免費(fèi)使用20條/天,如果需求量比較大,我們可以在自己的工程里集成了mob短信,然后上線登記,應(yīng)該可以獲得更多的免費(fèi)短信條數(shù),暫未嘗試。
2.下載SDK
在SDK下載欄目選擇SMS for Android,然后選擇相應(yīng)IDE對(duì)應(yīng)的SDK即可(本篇IDE是as)
下載后大概是這樣:

3.集成過程
申請(qǐng)到了key和secret后就是集成到自己的工程中了。mob主要提供兩種接口方式:1)使用官方自帶的UI;2)使用無GUI接口。
3.1.配置SDK
這已經(jīng)是使用第三方接口的老規(guī)矩了。官網(wǎng)文檔我就不貼了,著實(shí)看著不舒服,在這里只貼自己的。
首先是在工程的libs下添加jar包和.aar文件。

然后在build.gradle中添加依賴項(xiàng)

在AndroidManifest中添加相應(yīng)權(quán)限和注冊相應(yīng)的activity
<!-- mob短信 需要的權(quán)限 --> <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中注冊activity --> <!-- Mob短信(如果使用無GUI的,這個(gè)activity應(yīng)該可以不需要了,自己沒試過,就先在這注冊著吧) --> <activity android:name="com.mob.tools.MobUIShell" android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:windowSoftInputMode="stateHidden|adjustResize" > </activity>
3.2.調(diào)用接口發(fā)送短信
前面提到了,mob短息提供有GUI和無GUI的兩種方式,無論哪種方式,都需要對(duì)SMSSDK先初始化,再調(diào)用接口。
初始化:SMSSDK.initSDK(LoginActivity.this, "App Key", "App Secret");
1)有GUI,即使用mob提供的界面



方法如下:
registerText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//首先初始化SMSSDK
SMSSDK.initSDK(LoginActivity.this, "App Key", "App Secret");
RegisterPage registerPage = new RegisterPage();
//回調(diào)函數(shù)
registerPage.setRegisterCallback(new EventHandler()
{
public void afterEvent(int event, int result, Object data)
{
// 解析結(jié)果
if (result == SMSSDK.RESULT_COMPLETE)
{
//提交驗(yàn)證碼成功
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE)
{
}
//提交驗(yàn)證碼成功,此時(shí)已經(jīng)驗(yàn)證成功了
else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE)
{
}
}
}
});
registerPage.show(LoginActivity.this);
}
});
2)無GUI
這種情況一般是使用自己的activity界面,然后集成短信功能,比如一個(gè)簡單的注冊。
//我只提供一些關(guān)鍵代碼,其他部分就不提供了,太多,看起來太雜
public class ActivityMessageRegister extends Activity
{
private static final int CODE_ING = 1; //已發(fā)送,倒計(jì)時(shí)
private static final int CODE_REPEAT = 2; //重新發(fā)送
private static final int SMSDDK_HANDLER = 3; //短信回調(diào)
private int TIME = 60;//倒計(jì)時(shí)60s
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_register);
initView();//界面初始化
initSDK();//短信初始化
}
//初始化界面
void initView()
{
userPhoneText = (EditText)findViewById(R.id.user_phone_input);
userPasswordText = (EditText)findViewById(R.id.user_password_input);
userNameText = (EditText)findViewById(R.id.user_name_input);
registerButton = (Button)findViewById(R.id.register_button);
registerButton.setOnClickListener(new OnClickListener());
loginView = (TextView)findViewById(R.id.login_view);
getCodeButton = (Button)findViewById(R.id.get_code_button);
getCodeButton.setOnClickListener(new OnClickListener());
codeText = (EditText)findViewById(R.id.code_view);
//
...
//
}
//初始化SMSSDK
private void initSDK()
{
SMSSDK.initSDK(this, "App Key", "App Secret");
eventHandler = 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;
msg.what = SMSDDK_HANDLER;
handler.sendMessage(msg);
}
};
// 注冊回調(diào)監(jiān)聽接口
SMSSDK.registerEventHandler(eventHandler);
}
//監(jiān)聽函數(shù)
private class OnClickListener implements View.OnClickListener
{
@Override
public void onClick(View v) {
userPhone = userPhoneText.getText().toString();
switch (v.getId()) {
case R.id.get_code_button://獲取驗(yàn)證碼
new AlertDialog.Builder(ActivityMessageRegister.this)
.setTitle("發(fā)送短信")
.setMessage("我們將把驗(yàn)證碼發(fā)送到以下號(hào)碼:\n"+"+86:"+userPhone)
.setPositiveButton("確定", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
SMSSDK.getVerificationCode("86", userPhone);
getCodeButton.setClickable(false);
new Thread(new Runnable()
{
@Override
public void run()
{
for (int i = 60; i > 0; i--)
{
handler.sendEmptyMessage(CODE_ING);
if (i <= 0)
{
break;
}
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
handler.sendEmptyMessage(CODE_REPEAT);
}
}).start();
}
})
.create()
.show();
break;
case R.id.register_button://注冊
SMSSDK.submitVerificationCode("86", userPhone, codeText.getText().toString());//對(duì)驗(yàn)證碼進(jìn)行驗(yàn)證->回調(diào)函數(shù)
break;
default:
break;
}
}
}
Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
switch (msg.what)
{
case CODE_ING://已發(fā)送,倒計(jì)時(shí)
getCodeButton.setText("重新發(fā)送("+--TIME+"s)");
break;
case CODE_REPEAT://重新發(fā)送
getCodeButton.setText("獲取驗(yàn)證碼");
getCodeButton.setClickable(true);
break;
case SMSDDK_HANDLER:
int event = msg.arg1;
int result = msg.arg2;
Object data = msg.obj;
//回調(diào)完成
if (result == SMSSDK.RESULT_COMPLETE)
{
//驗(yàn)證碼驗(yàn)證成功
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE)
{
Toast.makeText(ActivityMessageRegister.this, "驗(yàn)證成功", Toast.LENGTH_LONG).show();
if (check())//其他合法性的檢測
{
UserModel user = new UserModel();
user.setUserId(MyUUID.getUUID()); //id
user.setUserPhone(userPhone);
user.setUserPassword(MD5.md5(userPassword)); //md5加密
user.setUserGender(gender); //性別
user.setUserName(userName);
user.setUserBirthday("19920401"); //暫時(shí)為空
//user.setUserIdCard(userIdCard);
//user.setUserImage(""); //暫時(shí)為空
//注冊->服務(wù)器
UserController.userRegister(user, handler);
}
}
//已發(fā)送驗(yàn)證碼
else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE)
{
Toast.makeText(getApplicationContext(), "驗(yàn)證碼已經(jīng)發(fā)送",
Toast.LENGTH_SHORT).show();
} else
{
((Throwable) data).printStackTrace();
}
}
if(result==SMSSDK.RESULT_ERROR)
{
try {
Throwable throwable = (Throwable) data;
throwable.printStackTrace();
JSONObject object = new JSONObject(throwable.getMessage());
String des = object.optString("detail");//錯(cuò)誤描述
int status = object.optInt("status");//錯(cuò)誤代碼
if (status > 0 && !TextUtils.isEmpty(des)) {
Toast.makeText(getApplicationContext(), des, Toast.LENGTH_SHORT).show();
return;
}
} catch (Exception e) {
//do something
}
}
break;
case R.id.register_status:
String result_code = msg.getData().getString("result").toString();
if("1".equals(result_code))
{
Toast.makeText(ActivityMessageRegister.this, "注冊成功", Toast.LENGTH_LONG).show();
Intent intent = new Intent(ActivityMessageRegister.this,LoginActivity.class);
intent.putExtra("userPhone", userPhone);
ActivityMessageRegister.this.setResult(RESULE_CODE, intent);
//startActivity(intent);
finish();
}else
{
Toast.makeText(ActivityMessageRegister.this, "注冊失敗", Toast.LENGTH_LONG).show();
}
break;
case R.id.check_phone_exist://手機(jī)號(hào)是否已存在
String result_code_2 = msg.getData().getString("result").toString();
if("1".equals(result_code_2))
{
errPhoneText.setText("手機(jī)號(hào)碼已經(jīng)注冊,請(qǐng)換用其他號(hào)碼");
resultMap.put("phone", false);
}
else
{
errPhoneText.setText("");
resultMap.put("phone", true);
}
break;
}
}
};
}
OK,基本就大功告成。
三.問題
集成中可能會(huì)出現(xiàn)幾個(gè)問題:
1.無法接收短信驗(yàn)證碼
mob默認(rèn)是開啟了智能驗(yàn)證的,也意味著如果一個(gè)號(hào)碼通過了一次驗(yàn)證碼驗(yàn)證,那之后再次進(jìn)行短信驗(yàn)證時(shí),就會(huì)智能驗(yàn)證通過,而此時(shí)是不會(huì)接收到驗(yàn)證碼的,因?yàn)閙ob不會(huì)下發(fā)驗(yàn)證碼。這就對(duì)我們的測試造成了一定的影響,有時(shí)候,我們始終無法接收到驗(yàn)證碼,原因就在這里。進(jìn)入后臺(tái),將智能驗(yàn)證功能關(guān)閉就可以了。后臺(tái)中心->短信設(shè)置->智能驗(yàn)證
這里寫圖片描述
2.短信驗(yàn)證成功后,并未執(zhí)行相應(yīng)的代碼,而是返回到了某一個(gè)界面
還是有可能是因?yàn)橹悄茯?yàn)證的原因。
eventHandler = new EventHandler() {
@Override
public void afterEvent(int event, int result, Object data)
{
if (result == SMSSDK.RESULT_COMPLETE)
{
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE)
{
//官方文檔中說了,如果是智能驗(yàn)證只需要在這里對(duì)data進(jìn)行判斷就可以了
if((Boolean)data)//是智能驗(yàn)證
{
//如果增加了這條if語句,那么就算關(guān)閉了智能驗(yàn)證,此時(shí)的data強(qiáng)制轉(zhuǎn)換成了Boolean也是為true的,所以并不會(huì)執(zhí)行后面的相應(yīng)代碼,所以,如果在集成的時(shí)候不需要智能驗(yàn)證,最好的方式就是不去管這個(gè)功能。
}
else
{
//非智能
}
}
}
}
所以,最妥的方式,就是徹底舍棄掉智能驗(yàn)證功能。
以上就是本文的全部內(nèi)容,希望對(duì)大家學(xué)習(xí)Android軟件編程有所幫助。
- Android如何通過手機(jī)獲取驗(yàn)證碼來完成注冊功能
- Android開發(fā)中通過手機(jī)號(hào)+短信驗(yàn)證碼登錄的實(shí)例代碼
- Android實(shí)現(xiàn)短信驗(yàn)證碼獲取自動(dòng)填寫功能(詳細(xì)版)
- Android獲取和讀取短信驗(yàn)證碼的實(shí)現(xiàn)方法
- Android實(shí)現(xiàn)自動(dòng)提取短信驗(yàn)證碼功能
- Android實(shí)現(xiàn)短信驗(yàn)證碼自動(dòng)填寫功能
- Android獲取短信驗(yàn)證碼的實(shí)現(xiàn)方法
- Android實(shí)現(xiàn)常見的驗(yàn)證碼輸入框?qū)嵗a
- Android自定義控件通用驗(yàn)證碼輸入框的實(shí)現(xiàn)
- Android實(shí)現(xiàn)隨機(jī)生成驗(yàn)證碼
相關(guān)文章
android 點(diǎn)擊EditText始終不彈出軟件鍵盤實(shí)現(xiàn)代碼
這篇文章主要介紹了android 點(diǎn)擊EditText始終不彈出軟件鍵盤實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-11-11
Android使用AudioRecord實(shí)現(xiàn)暫停錄音功能實(shí)例代碼
本篇文章主要介紹了Android使用AudioRecord實(shí)現(xiàn)暫停錄音功能實(shí)例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下2017-06-06
android自定義imageview實(shí)現(xiàn)圓角圖片
這篇文章主要為大家詳細(xì)介紹了android自定義imageview實(shí)現(xiàn)圓角圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
Android實(shí)現(xiàn)繞球心旋轉(zhuǎn)的引導(dǎo)頁效果
本篇文章主要介紹了Android實(shí)現(xiàn)繞球心旋轉(zhuǎn)的引導(dǎo)頁效果,想要實(shí)現(xiàn)此效果的同學(xué)可以參考一下本文。2016-11-11
Android如何從實(shí)現(xiàn)到封裝一個(gè)MVP詳解
原生的 MVC 框架遇到大規(guī)模的應(yīng)用,就會(huì)變得代碼難讀,不好維護(hù),無法測試的囧境。因此,Android 開發(fā)方面也有很多對(duì)應(yīng)的框架來解決這些問題。所以這篇文章主要給大家介紹了關(guān)于Android如何從實(shí)現(xiàn)到封裝一個(gè)MVP的相關(guān)資料,需要的朋友可以參考下。2017-09-09
Android網(wǎng)絡(luò)請(qǐng)求庫android-async-http介紹
這篇文章主要介紹了Android網(wǎng)絡(luò)請(qǐng)求庫android-async-http介紹,本文講解了android-async-http的概念、特征以及使用實(shí)例,需要的朋友可以參考下2015-06-06
實(shí)例詳解Android 獲取短信會(huì)話列表
本文通過實(shí)例詳解android獲取短信會(huì)話列表的全部內(nèi)容,涉及到android獲取短信列表的相關(guān)知識(shí),對(duì)android會(huì)話列表相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2015-12-12
Flutter仿微信通訊錄實(shí)現(xiàn)自定義導(dǎo)航條的示例代碼
某些頁面比如我們在選擇聯(lián)系人或者某個(gè)城市的時(shí)候需要快速定位到我們需要的選項(xiàng),一般都會(huì)需要像微信通訊錄右邊有一個(gè)導(dǎo)航條一樣的功能,本文將利用Flutter實(shí)現(xiàn)這一效果,需要的可以參考一下2022-04-04

