Android Studio精彩案例(五)《JSMS短信验证码功能实现》

转载本专栏文章,请注明出处,尊重原创 。文章博客地址:道龙的博客

很多应用刚打开的时候,让我们输入手机号,通过短信验证码来登录该应用。那么,这个场景是怎么实现的呢?其实是很多开放平台提供了短信验证功能的接口供我们使用,我们只需要关心客户端,无需关心服务端的业务逻辑,而且更加稳定安全。今天这篇文章就通过Jpush官方的JSMS模块,来实现短信验证登录功能。虽然,Jpush对于极光推送是非常有名出色的,短信验证也是它官网的新内容,不过,多种开放平台使用方式大同小异,而且综合对比,Jpush官网的短信验证使用起来很简单!既然人家给了接口,就来感受一下它的短信验证的实现吧。

首先咱们了解一下短信验证的请求流程:

1.以用户提供的手机号码作为参数,请求连接到JSMS的服务器

2.JSMS服务器校验号码格式成功,请求短信服务商发送短信验证码到该手机号

3.手机终端接收到验证码,用户输入验证码

4.验证码传入应用后台服务端,服务端通过JSMS接口验证,再把验证结果传回手机端

JPush官方地址:http://docs.jiguang.cn/jsms/resources/

进入官网,JSMS模块,官网是这么给出的

短信验证码概述

功能

极光面向开发者提供短信验证码服务,主要包括:

  • SDK 短信验证功能,满足 App 短信验证需求。
  • REST API 短信验证,主要满足网站和其他终端访问需求。

主要场景

  • 用户注册;
  • 登录验证;
  • 关键信息修改;
  • 支付确认;
  • 人员身份有效性确认。

试用步骤

  • 注册成为极光开发者。
  • 通过极光后台创建 APP 得到 AppKey(如果之前创建过可以通用)。

官网概述的确言简意赅,我觉得使用图文告知您,可能更贴切一些。看下图:

步骤一 (获取appkey)

1.在极光官网平台上新建短信应用(根据要求包名和应用名称填写好)

Android Studio精彩案例(五)《JSMS短信验证码功能实现》

2.获取得到Jpush_AppKey。

Android Studio精彩案例(五)《JSMS短信验证码功能实现》

步骤二  (导入第三方库和so文件)

1.用Android studio打开应用

2.切换应用状态Android为Project状态

Android Studio精彩案例(五)《JSMS短信验证码功能实现》

3.在libs文件夹下把对应的jar文件拷入  然后as libraries

Android Studio精彩案例(五)《JSMS短信验证码功能实现》

步骤三 (填写配置文件)

1.配置应用权限

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

2.配置meta (appkey 从平台上新建的对应应用中来)

    <meta-data android:name="JPUSH_APPKEY" android:value="You JPUSH_APPKEY"/>  

步骤四(初始化以及调用)

1.新建Application初始化

public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
SMSSDK.getInstance().initSdk(this);
SMSSDK.getInstance().setIntervalTime(30*1000);
}
}

接口的意思是:

SMSSDK.getInstance().init(this);

该接口为初始化接口,主要是检测一些配置信息,如果配置错误将会初始化失败,将会打印错误日志。调用其它接口前必须先调用该接口,仅且仅需调用一次,建议在 Application 或初始 Activity 中调用。我这里自定义了一个Applicatiion,这样的话会排除一些可能存在的问题。

SMSSDK.getInstance().setIntervalTime(60000);

设置前后两次获取验证码的时间间隔,默认 30 秒。参数是一个时间间隔,单位是毫秒(ms)

2.在activity中使用

public class CommonSMSActivity extends Activity {

    private EditText editText;
private Button btn; private EditText codeText;
private Button signBtn; private TimerTask timerTask;
private Timer timer;
private int timess;
private ProgressDialog progressDialog; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash); progressDialog = new ProgressDialog(this);
editText = (EditText) findViewById(R.id.edt_code);
codeText = (EditText) findViewById(R.id.edt_write_code);
btn = (Button) findViewById(R.id.btn);
signBtn = (Button) findViewById(R.id.btn_sign); // 获取验证码
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String phoneNum = editText.getText().toString();
if(TextUtils.isEmpty(phoneNum)){
Toast.makeText(CommonSMSActivity.this, "请输入手机号码", Toast.LENGTH_SHORT).show();
Log.e("执行", "请输入手机号码!");
return;
}
btn.setClickable(false);
// 开始倒计时
startTimer();
SMSSDK.getInstance().getSmsCodeAsyn(phoneNum, 1+"", new SmscodeListener() {
@Override
public void getCodeSuccess(final String uuid) {
Toast.makeText(CommonSMSActivity.this,uuid,Toast.LENGTH_SHORT).show();
Log.e("执行", "获取验证码成功!");
} @Override
public void getCodeFail(int errCode, final String errmsg) {
//失败后停止计时
stopTimer();
Toast.makeText(CommonSMSActivity.this,errmsg,Toast.LENGTH_SHORT).show();
Log.e("执行", "获取验证码失败,请重新获取!");
}
}); }
});
//开始验证
signBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { String code = codeText.getText().toString();
String phoneNum = editText.getText().toString(); if(TextUtils.isEmpty(code)){
Toast.makeText(CommonSMSActivity.this,"请输入验证码",Toast.LENGTH_SHORT).show();
Log.e("执行", "验证前请确保您已经输入验证码了!");
return;
}
if(TextUtils.isEmpty(phoneNum)){
Toast.makeText(CommonSMSActivity.this,"请输入手机号码",Toast.LENGTH_SHORT).show();
Log.e("执行", "验证前请确保您有输入手机号");
return;
}
progressDialog.setTitle("正在验证...");
progressDialog.show();
SMSSDK.getInstance().checkSmsCodeAsyn(phoneNum, code, new SmscheckListener() {
@Override
public void checkCodeSuccess(final String code) {
if(progressDialog!=null&&progressDialog.isShowing()){
progressDialog.dismiss();
}
Toast.makeText(CommonSMSActivity.this,code,Toast.LENGTH_SHORT).show();
Log.e("执行", "验证成功!");
} @Override
public void checkCodeFail(int errCode, final String errmsg) {
if(progressDialog!=null&&progressDialog.isShowing()){
progressDialog.dismiss();
}
Toast.makeText(CommonSMSActivity.this,errmsg,Toast.LENGTH_SHORT).show();
Log.e("执行", "验证失败!");
}
});
}
});
}
//开始计时
private void startTimer(){
timess = (int) (SMSSDK.getInstance().getIntervalTime()/1000);//获取短信时长
btn.setText(timess+"s");
if(timerTask==null){
timerTask = new TimerTask() {//启动task任务
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
timess--;
if(timess<=0){
stopTimer();//停止倒计时
return;
}
btn.setText(timess+"s");
}
});
}
};
}
if(timer==null){
timer = new Timer();
}
timer.schedule(timerTask, 1000, 1000);//每隔1s执行一次任务
}
private void stopTimer(){//停止计时
if(timer!=null){
timer.cancel();
timer=null;
}
if(timerTask!=null){
timerTask.cancel();
timerTask=null;
}
btn.setText("重新获取");
btn.setClickable(true);
}
}

这里的代码稍微有点长,核心的API说明一下:

  • SMSSDK 类:对外的类,该类为单例,调用该类的方法都需要获取该类的唯一实例,获得方法为 SMSSDK.getInstance()。

  • SmscodeListener:获取验证码的回调接口,在调用 SMSSDK 的 getSmsCode 时需要传入接口实例。

  • SmscheckListener:检查验证码的回调接口,在调用 SMSSDK 的 checkSmsCode 时需要传入接口实例。

SMSSDK.init(Context context)

接口说明

该接口为初始化接口,主要是检测一些配置信息,如果配置错误将会初始化失败,将会打印错误日志。调用其它接口前必须先调用该接口,仅且仅需调用一次,建议在 Application 或初始 Activity 中调用。

调用示例

SMSSDK.getInstance().init(this);

SMSSDK.getSmsCode(String phone, String tempId, SmscodeListener listener)

接口说明

获取验证码。

该接口是在非 UI 线程回调,需要在 UI 线程回调可调用 SMSSDK.getSmsCodeAsyn()。

参数说明

  • phone:手机号码
  • tempId:短信模板
  • listener:回调接口

调用示例

SMSSDK.getInstance().getSmsCodeAsyn("159xxxxxxxx", "1", new SmscodeListener() {
@Override
public void getCodeSuccess(final String uuid) {
// 获取验证码成功,uuid 为此次获取的唯一标识码。
} @Override
public void getCodeFail(int errCode, final String errMsg) {
// 获取验证码失败 errCode 为错误码,详情请见文档后面的错误码表;errMsg 为错误描述。
}
});

SMSSDK.checkSmsCode(String phone, String code, SmscheckListener listener)

接口说明

验证码验证接口。

该接口是在非 UI 线程回调,需要在 UI 线程回调可调用 SMSSDK.checkSmsCodeAsyn()。

参数说明

  • phone:手机号码
  • code:短信验证码
  • listener:回调接口

调用示例

SMSSDK.getInstance().checkSmsCodeAsyn("159xxxxxxxx", "123456", new SmscheckListener() {
@Override
public void checkCodeSuccess(final String code) {
// 验证码验证成功,code 为验证码信息。
} @Override
public void checkCodeFail(int errCode, final String errMsg) {
// 验证码验证失败, errCode 为错误码,详情请见文档后面的错误码表;errMsg 为错误描述。
}
});

SMSSDK.setIntervalTime(long intervalTime)

接口说明

设置前后两次获取验证码的时间间隔,默认 30 秒。

参数说明

  • intervalTime:时间间隔,单位是毫秒(ms)。

调用示例

SMSSDK.getInstance().setIntervalTime(60000);    // 设置间隔时间为 60 秒

SMSSDK.getIntervalTime()

接口说明

获取当前设置的时间间隔。

返回值

  • long:单位为毫秒(ms)。

调用示例

SMSSDK.getInstance().getIntervalTime();

我们平时使用短信验证太频繁了,相信上边代码对你来说是soeasy;只不过是做了两个点击事件,然后获取短信以及验证短信交流jsms去处理了,我们并不需要实现业务逻辑。我们额外再做的,也就是启动倒计时任务罢了。

最后再贴上error可能的情况表:

错误码描述

错误码 错误码描述 备注
3001 请求超时  
3002 无效的手机号码  
4001 body 为空  
4002 无效的 AppKey  
4003 无效的来源  
4004 body 解密失败  
4005 aes key 解密失败  
4006 时间戳转化失败  
4007 body 格式不正确  
4008 无效时间戳  
4009 没有短信验证权限  
4011 发送超频 单个设备或同一手机号每天获取验证码次数(默认10次)
4013 模板不存在  
4014 extra 为空  
4015 验证码不正确  
4016 没有余额  
4017 验证码超时  
4018 重复验证  
2993 验证码校验失败 短信已下发但获取 uuid 异常
2994 本地数据有误  
2995 数据解析错误  
2996 两次请求不超过 1 分钟 本地校验
2997 未获取验证码  
2998 网络错误 没有网络等
2999 其它错误  

很多人以为已经完成了,其实不然!翻阅了很多有关jsms相关的博客,大家仅仅是给出了怎么使用,罗列了一堆代码。并没有运行截图。也未给出后面遇到问题的解释。不卖关子了,我们发现,上面的代码没有任何错误,运行也能成功。但是,运行发现一直提示no money的错误,并不能接收短信。这是因为我们仅仅是在开放平台集成了人家的功能,并没有作为真正的开发者使用这个功能。那么有什么办法吗?一张图说明一切吧:

Android Studio精彩案例(五)《JSMS短信验证码功能实现》

如果你是刚刚创建的账号,那么点击这个位置跟我的不一样,最下端会提醒你    “点击联系服务”  大致这个意思。那么你就填写完整个人信息并提交,成功后,就会获得每日20条免费短信的功能。其实,在公司实际开发中不会只给你20条的,到底后边怎么实现,到公司跟你老板商量吧!

最后,我们再来运行一下,看看效果:

Android Studio精彩案例(五)《JSMS短信验证码功能实现》

我使用的模拟器,短信下发到了我的手机。为了不暴露自己的手机号,就截了下方的验证部分。可以肯定的是,验证登录功能是实现完毕了~

刚才连续发了好几条验证信息。再看看后台数据吧:

Android Studio精彩案例(五)《JSMS短信验证码功能实现》

JSMS基本使用就介绍这么多,更多功能请参考官方文档。

参考文章:极光推送(短信验证)

Android学习之如何集成极光短信验证

喜欢我的朋友,可以关注我的博客。

也可以打开微信搜索公众号  Android程序员开发指南  或者手机扫描下方二维码 在公众号阅读更多Android文章。

微信公众号图片:

Android Studio精彩案例(五)《JSMS短信验证码功能实现》

上一篇:Tian Ji -- The Horse Racing


下一篇:efcore migration