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.在极光官网平台上新建短信应用(根据要求包名和应用名称填写好)
2.获取得到Jpush_AppKey。
步骤二 (导入第三方库和so文件)
1.用Android studio打开应用
2.切换应用状态Android为Project状态
3.在libs文件夹下把对应的jar文件拷入 然后as libraries
步骤三 (填写配置文件)
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的错误,并不能接收短信。这是因为我们仅仅是在开放平台集成了人家的功能,并没有作为真正的开发者使用这个功能。那么有什么办法吗?一张图说明一切吧:
如果你是刚刚创建的账号,那么点击这个位置跟我的不一样,最下端会提醒你 “点击联系服务” 大致这个意思。那么你就填写完整个人信息并提交,成功后,就会获得每日20条免费短信的功能。其实,在公司实际开发中不会只给你20条的,到底后边怎么实现,到公司跟你老板商量吧!
最后,我们再来运行一下,看看效果:
我使用的模拟器,短信下发到了我的手机。为了不暴露自己的手机号,就截了下方的验证部分。可以肯定的是,验证登录功能是实现完毕了~
刚才连续发了好几条验证信息。再看看后台数据吧:
JSMS基本使用就介绍这么多,更多功能请参考官方文档。
参考文章:极光推送(短信验证)
喜欢我的朋友,可以关注我的博客。
也可以打开微信搜索公众号 Android程序员开发指南 或者手机扫描下方二维码 在公众号阅读更多Android文章。
微信公众号图片:
Android Studio精彩案例(五)《JSMS短信验证码功能实现》的更多相关文章
- jQuery实现倒计时重新发送短信验证码功能示例
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- SpringSceurity(4)---短信验证码功能实现
SpringSceurity(4)---短信验证码功能实现 有关SpringSceurity系列之前有写文章 1.SpringSecurity(1)---认证+授权代码实现 2.SpringSecur ...
- Java调用WebService接口实现发送手机短信验证码功能,java 手机验证码,WebService接口调用
近来由于项目需要,需要用到手机短信验证码的功能,其中最主要的是用到了第三方提供的短信平台接口WebService客户端接口,下面我把我在项目中用到的记录一下,以便给大家提供个思路,由于本人的文采有限, ...
- 四:java调接口实现发送手机短信验证码功能
1.点击获取验证码之前的样式: 2.输入正确的手机号后点击获取验证码之后的样式: 3.如果手机号已经被注册的样式: 4.如果一个手机号一天发送超过3次就提示不能发送: 二:前台的注册页面的代码:reg ...
- 这是一个简单的前台短信验证码功能 ajax实现异步处理 (发送和校验)
<script type="text/javascript"> var InterValObj; //timer变量,控制时间 var count = 60; //间隔 ...
- java + maven 实现发送短信验证码功能
如何使用java + maven的项目环境发送短信验证码,本文使用的是榛子云短信 的接口. 1. 安装sdk 下载地址: http://smsow.zhenzikj.com/doc/sdk.html ...
- 利用WeX5给手机APP增加短信验证码功能
帖子来源:http://bbs.wex5.com/thread-70908-1-1.html 遇到一个手机APP项目客户要求注册到APP上的用户手机号必须是真实的通过X5平台整合短信发送平台接口完成了 ...
- Java加腾讯云实现短信验证码功能
一.概要 现如今在日常工作和生活中短信验证码对于我们来说是非常熟悉的,比较常见的注册账号或者交易支付时候,手机会收到一个短信验证码,我们可以通过验证码来有效验证身份,避免一些信息被盗. 验证身份 目前 ...
- Android Studio精彩案例(一)《ActionBar和 ViewPager版仿网易新闻客户端》
转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 为了能更好的分享高质量的文章,所以开设了此专栏.文章代码都以Android Studio亲测运行,读者朋友可在后面直接下载源码.该专栏 ...
随机推荐
- Java面试题—初级(2)
11.是否可以从一个static方法内部发出对非static方法的调用? 不可以.因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用 ...
- Go-GRPC 初体验
grpc 跟常见的client-server模型相似(doubbo)grpc 编码之前需要准备以下环境: 安装protobuf,grpc的client与server之间消息传递使用的protoc格式消 ...
- html如何实现的
超文本标记语言是标准通用标记语言下的一个应用,也是一种规范,一种标准,它通过标记符号来标记要显示的网页中的各个部分.网页文件本身是一种文本文件,通过在文本文件中添加标记符,可以告诉浏览器如何显示其中的 ...
- javascript中的事件类型
表单事件 submit reset click change focus blur input window事件 load DomContentLoaded readyStatechange unlo ...
- JavaScript数据结构与算法(二) 队列的实现
TypeScript方式源码 class Queue { items = []; public enqueue(element) { this.items.push(element); } publi ...
- 深入探索.NET框架内部了解CLR如何创建运行时对象
原文地址:http://msdn.microsoft.com/en-us/magazine/cc163791.aspx 原文发布日期: 9/19/2005 原文已经被 Microsoft 删除了,收集 ...
- [HAOI 2010]软件安装
Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和 ...
- [JLOI 2014]松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想 ...
- [ZJOI2015]幻想乡战略游戏
Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...
- bzoj3048[Usaco2013 Jan]Cow Lineup 尺取法
3048: [Usaco2013 Jan]Cow Lineup Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 225 Solved: 159[Subm ...