Android开发工程中集成mob短信验证码功能的方法
作者:不正经的小二哥 发布时间:2022-12-15 06:37:02
一.前言
现在的app基本上都需要用到短信功能,注册时或者有消息通知时需要给用户发送一条短信,但是对于个人开发者来说,去买第三方的短信服务实在是有点奢侈,很好的是mob为我们提供了免费的短信验证码服务功能,我不是打广告,的确觉得这项服务很不错。那么下面就简单讲一下如何在自己的工程里集成mob的短信功能,其实整个流程并不复杂,只是个人觉得mob的官方文档有点小乱,官方Demo也有点小复杂,同时有一些细节地方容易被忽视,也会导致一些问题。
PS:太喜欢mob的logo了。
二.实现过程
本篇只涉及Android,如果是IOS系统,还望自己斟酌,希望本篇文章也能给您提供帮助,同时IDE是Android Studio。
1.key申请
申请地址:http://www.mob.com,在产品中心选择短信验证码SDK,然后完成相应的注册和申请工作;
进入自己的后台中心,就可以看见自己的App Key和App Secret:
整体趋势栏给我们展示了一些短信服务使用情况。未上线登记时,我们可以免费使用20条/天,如果需求量比较大,我们可以在自己的工程里集成了mob短信,然后上线登记,应该可以获得更多的免费短信条数,暂未尝试。
2.下载SDK
在SDK下载栏目选择SMS for Android,然后选择相应IDE对应的SDK即可(本篇IDE是as)
下载后大概是这样:
3.集成过程
申请到了key和secret后就是集成到自己的工程中了。mob主要提供两种接口方式:1)使用官方自带的UI;2)使用无GUI接口。
3.1.配置SDK
这已经是使用第三方接口的老规矩了。官网文档我就不贴了,着实看着不舒服,在这里只贴自己的。
首先是在工程的libs下添加jar包和.aar文件。
然后在build.gradle中添加依赖项
在AndroidManifest中添加相应权限和注册相应的activity
<!-- mob短信 需要的权限 -->
<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的,这个activity应该可以不需要了,自己没试过,就先在这注册着吧) -->
<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.调用接口发送短信
前面提到了,mob短息提供有GUI和无GUI的两种方式,无论哪种方式,都需要对SMSSDK先初始化,再调用接口。
初始化: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();
//回调函数
registerPage.setRegisterCallback(new EventHandler()
{
public void afterEvent(int event, int result, Object data)
{
// 解析结果
if (result == SMSSDK.RESULT_COMPLETE)
{
//提交验证码成功
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE)
{
}
//提交验证码成功,此时已经验证成功了
else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE)
{
}
}
}
});
registerPage.show(LoginActivity.this);
}
});
2)无GUI
这种情况一般是使用自己的activity界面,然后集成短信功能,比如一个简单的注册。
//我只提供一些关键代码,其他部分就不提供了,太多,看起来太杂
public class ActivityMessageRegister extends Activity
{
private static final int CODE_ING = 1; //已发送,倒计时
private static final int CODE_REPEAT = 2; //重新发送
private static final int SMSDDK_HANDLER = 3; //短信回调
private int TIME = 60;//倒计时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);
}
};
// 注册回调监听接口
SMSSDK.registerEventHandler(eventHandler);
}
//监听函数
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://获取验证码
new AlertDialog.Builder(ActivityMessageRegister.this)
.setTitle("发送短信")
.setMessage("我们将把验证码发送到以下号码:\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());//对验证码进行验证->回调函数
break;
default:
break;
}
}
}
Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
switch (msg.what)
{
case CODE_ING://已发送,倒计时
getCodeButton.setText("重新发送("+--TIME+"s)");
break;
case CODE_REPEAT://重新发送
getCodeButton.setText("获取验证码");
getCodeButton.setClickable(true);
break;
case SMSDDK_HANDLER:
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(ActivityMessageRegister.this, "验证成功", 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"); //暂时为空
//user.setUserIdCard(userIdCard);
//user.setUserImage(""); //暂时为空
//注册->服务器
UserController.userRegister(user, handler);
}
}
//已发送验证码
else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE)
{
Toast.makeText(getApplicationContext(), "验证码已经发送",
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");//错误描述
int status = object.optInt("status");//错误代码
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://手机号是否已存在
String result_code_2 = msg.getData().getString("result").toString();
if("1".equals(result_code_2))
{
errPhoneText.setText("手机号码已经注册,请换用其他号码");
resultMap.put("phone", false);
}
else
{
errPhoneText.setText("");
resultMap.put("phone", true);
}
break;
}
}
};
}
OK,基本就大功告成。
三.问题
集成中可能会出现几个问题:
1.无法接收短信验证码
mob默认是开启了智能验证的,也意味着如果一个号码通过了一次验证码验证,那之后再次进行短信验证时,就会智能验证通过,而此时是不会接收到验证码的,因为mob不会下发验证码。这就对我们的测试造成了一定的影响,有时候,我们始终无法接收到验证码,原因就在这里。进入后台,将智能验证功能关闭就可以了。后台中心->短信设置->智能验证
这里写图片描述
2.短信验证成功后,并未执行相应的代码,而是返回到了某一个界面
还是有可能是因为智能验证的原因。
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)
{
//官方文档中说了,如果是智能验证只需要在这里对data进行判断就可以了
if((Boolean)data)//是智能验证
{
//如果增加了这条if语句,那么就算关闭了智能验证,此时的data强制转换成了Boolean也是为true的,所以并不会执行后面的相应代码,所以,如果在集成的时候不需要智能验证,最好的方式就是不去管这个功能。
}
else
{
//非智能
}
}
}
}
所以,最妥的方式,就是彻底舍弃掉智能验证功能。


猜你喜欢
- (1) main.xml 代码如下:(声明四个按钮控件) XML代码: <?xml version="1.0" e
- 前言下面大部分内容来源于网上的相关帖子和官网,自己简单写了个demo体验了下,个人感觉mybatis的缓存并不是很合适查询做缓存时,遇到更新
- 介绍在分布式系统、微服务架构大行其道的今天,服务间互相调用出现失败已经成为常态。如何处理异常,如何保证数据一致性,成为微服务设计过程中,绕不
- 一、No serializer found for class org.hibernate.proxy.pojo.bytebuddy.Byt
- 本文实例讲述了Android编程实现的一键锁屏程序。分享给大家供大家参考,具体如下:据笔者了解,所有的Android手机都用电源键来手动锁屏
- 今年新开Java课程第一步就是…配置环境就从Java的环境配置开始好了以下是正式的步骤首先,从Oracle的官网下载jdk的安装包点我下载J
- 前言本文将演示如何将字符串的单词倒序输出。注意:在这里我不是要将“John” 这样的字符串倒序为成“nhoJ”。这是不一样的,因为它完全倒序
- 今天跟大家分享一个利用外部Jar包来实现Java操作CSV文件一.资源下载1.直接下载Jar包:javacsv-2.0.jar2.利用Mav
- 到底什么是反射呢???反射的核心就是JVM在运行时才动态加载类或调用方法,访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。每
- 声明:下面的实例全部在linux下尝试,window下未尝试。有兴趣者可以试一下。文章针c初学者。c语言的强符号和弱符号是c初学者经常容易犯
- 下面给大家介绍spring不能注入static变量的原因,具体详情如下所示:Spring 依赖注入 是依赖 set方法set方法是 是普通的
- 前言当你编写一个应用时,你通常都会希望用户能够定制化他们和应用交互的方式,以及应用与系统进行交互的方式。这种方式通常被称为 &ldq
- 概述LruCache的核心原理就是对LinkedHashMap的有效利用,它的内部存在一个LinkedHashMap成员变量,值得注意的4个
- Feign进行调用@FeignClient 找不到通过Feign 进行调用这里配置spring-cloud 版本为 M8的 <
- 在之前的博客中已经为大家介绍了,如何在win环境下配置DNK程序,本篇我将带大家实现一个简单的Hello jni程序,让大家真正感受一下ND
- 打开ITerm终端进入命令输入,sudo su,输入密码创建.bash_profile文件touch .bash_profile打开.bas
- 再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上
- 归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序
- Android USB转串口通信开发实例详解好久没有写文章了,年前公司新开了一个项目,是和usb转串口通信相关的,需求是用安卓平
- 最近在做上传文件的服务,简单看了网上的教程。结合实践共享出代码。由于网上的大多数没有服务端的代码,这可不行呀,没服务端怎么调试呢。Ok,先上