『实践』Android之短信验证码(用的Mob短信验证)
1、参考资料
Mob网站:http://www.mob.com/
Mob在Github上的例子:https://github.com/MobClub/SMSSDK-for-Android
教程:http://www.cnblogs.com/lizhanqi/p/5720962.html
教程的源代码: http://git.oschina.net/lizhanqi/MobSMSDemo
Dialog教程:http://blog.csdn.net/liang5630/article/details/44098899
定时器教程:http://www.cnblogs.com/wansho/p/5104335.html
2、前期准备
(1)Mob网站上下载SMS对应的SDK,解压出来为图1,打开图1,将其中的文件拷贝到as项目中的libs文件夹下,另外在add as library。

图1

图2
(2)在as项目中的AndroidManifest.xml文件中添加图3所需权限,由于SMS权限为危险权限,所以还要动态申请,这在下面代码中会有体现。注意权限是写在application外面,不是里面。

图3
(3)如果图4中的targetSdkVersion大于22,那么在代码中必须动态申请权限。

图4
(4)在as项目中的图7中的build.gradle文件中添加图5和图6红色框中内容。

图5

图6

图7
(5)在Mob网站上申请App Key和App Secret。

图8
(6)Toast

3、代码(没整理,将就看)
此代码是不使用Mob自带的GUI的接口调用
简单的讲一下:
- 启动SKD:SMSSDK.initSDK(this, "您的appkey", "您的appsecret");
- 注册回调接口:registerEventHandler(EventHandler handler);
- 注销回调接口:unregisterEventHandler(EventHandler handler);注册回调接口和注销回调接口必须配套使用,否则可能内存泄漏。
- EventHandler是操作回调,其中的afterEvent在操作结束时被触发。
- afterEvent(int event, int result, Object data):参数event表示操作的类型,data是事件操作结果,其具体取值根据参数result而定。result是操作结果,为SMSSDK.RESULT_COMPLETE表示操作成功,为SMSSDK.RESULT_ERROR表示操作失败。
- 请求获取短信验证码,在监听(eventHandle)中返回:getVerificationCode(String country, String phone);
- 提交短信验证码,在监听(eventHandle)中返回:submitVerificationCode(String country, String phone, String code);
- 备注:在EventHandler的4个回调方法都可能不在UI线程下,因此如果要在其中执行UI操作,请务必使用Handler发送一个消息给UI线程处理。
package com.gxu.lepao.activity; import android.Manifest;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.gxu.lepao.R;
import com.gxu.lepao.model.UserInfo;
import org.litepal.crud.DataSupport;//LitePal开源数据库框架
import java.util.List;
import cn.smssdk.EventHandler;//Mob短信验证码
import cn.smssdk.SMSSDK;//Mob短信验证码 /**
* Created by ljy on 2017-05-21.
* 获取和验证短信验证码界面
*/ public class RegisterActivity extends BaseActivity { private EditText phoneEdit;
private EditText smsEdit;
private Button getSms;
private Button submitSms;
private TextView login;
private TextView reset;
private CountDownTimer countDownTimer;
//倒计时
private int TIME = 60;
//这是中国区号,如果需要其他国家列表,可以使用getSupportedCountries();获得国家区号
public String country = "86";
//APPKEY
private static String appKey = "......";
// 填写从短信SDK应用后台注册得到的APPSECRET
private static String appSecret = "......";
//表示是否使用了registerEventHandler
private boolean ready; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("RegisterActivity","Task; id is " + getTaskId());
setContentView(R.layout.activity_register);
// 初始化界面
initView();
//初始化SMSSDK
initSDK();
//获取验证码按钮监听
getSms.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
boolean isLogin = false;
//判断手机号码是否已注册过
isLogin = isRegister();
if(!TextUtils.isEmpty(phoneEdit.getText().toString())){
if(!isLogin){
//发送短信权限
if(ContextCompat.checkSelfPermission(RegisterActivity.this
,Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED){
//显示申请权限弹窗
showRequestPermission();
}else{
//弹窗确认
alterWarning();
}
}else{
Toast.makeText(RegisterActivity.this,"此手机号码已经注册过",Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(RegisterActivity.this,"请输入手机号码",Toast.LENGTH_SHORT).show();
}
}
});
//提交验证码按钮监听
submitSms.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
String sms = smsEdit.getText().toString();
String phone = phoneEdit.getText().toString();
if(!TextUtils.isEmpty(sms)){
//提交验证码和手机号码到Mob,回调在eventHandle中获得
SMSSDK.submitVerificationCode( country, phone, sms);
}else{
Toast.makeText(RegisterActivity.this,"请输入验证码",Toast.LENGTH_SHORT).show();
}
}
});
login.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this,LoginActivity.class);
startActivity(intent);
}
});
reset.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this,ResetPwdActivity.class);
startActivity(intent);
}
});
} //申请权限弹窗
private void showRequestPermission(){
//先new出一个监听器,设置好监听
DialogInterface.OnClickListener dialogOnclicListener=new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
switch(which){
case Dialog.BUTTON_POSITIVE:
//接收短信权限
ActivityCompat.requestPermissions(RegisterActivity.this,new String[]{Manifest.permission.RECEIVE_SMS},1);
//发送短信权限
ActivityCompat.requestPermissions(RegisterActivity.this,new String[]{Manifest.permission.SEND_SMS},2);
//弹窗确认
alterWarning();
break;
case Dialog.BUTTON_NEGATIVE:
Toast.makeText(RegisterActivity.this, "拒绝" + which, Toast.LENGTH_SHORT).show();
break;
}
}
};
//dialog参数设置
AlertDialog.Builder builder=new AlertDialog.Builder(RegisterActivity.this); //先得到构造器
builder.setTitle("申请权限"); //设置标题
builder.setMessage("要允许lepao接收验证码短信吗?"); //设置内容
builder.setIcon(R.mipmap.ic_launcher);//设置图标,图片id即可
builder.setPositiveButton("允许",dialogOnclicListener);
builder.setNegativeButton("拒绝", dialogOnclicListener);
builder.create().show();
} //申请权限
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode){
case 1:
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//initSDK();
Toast.makeText(this,"你授权。。。接收短信权限",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this,"你拒绝。。。接收短信权限",Toast.LENGTH_SHORT).show();
}
break;
case 2:
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,"你授权。。。发送短信权限",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this,"你拒绝。。。发送短信权限",Toast.LENGTH_SHORT).show();
}
break;
default:
}
} // 初始化短信SDK
private void initSDK() {
SMSSDK.initSDK(this, appKey, appSecret, true);
//final Handler handler = new Handler();
EventHandler eventHandler = new EventHandler() {
public void afterEvent(int event, int result, Object data) {
//回调完成
if (result == SMSSDK.RESULT_COMPLETE)
{
//验证码验证成功
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE)
{
toast("验证成功");
Intent intent = new Intent(RegisterActivity.this,SetPwdActivity.class);
intent.putExtra("phone",phoneEdit.getText().toString());
startActivity(intent);
finish();
}
//已发送验证码
else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE)
{
toast("验证码已经发送");
} else
{
((Throwable) data).printStackTrace();
String str = data.toString();
toast(str);
}
}
if(result==SMSSDK.RESULT_ERROR) {
toast("验证码错误");
} }
};
// 注册回调监听接口
SMSSDK.registerEventHandler(eventHandler);
ready = true;
} //吐司的一个小方法
private void toast(final String str) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(RegisterActivity.this, str, Toast.LENGTH_SHORT).show();
}
});
} //销毁短信注册
@Override
protected void onDestroy() {
// 注销回调接口registerEventHandler必须和unregisterEventHandler配套使用,否则可能造成内存泄漏。
if(ready){
SMSSDK.unregisterAllEventHandler();
}
super.onDestroy();
} //初始化界面
private void initView(){
phoneEdit = (EditText) findViewById(R.id.phone);
smsEdit = (EditText) findViewById(R.id.sms);
getSms = (Button) findViewById(R.id.getSms);
submitSms = (Button) findViewById(R.id.submitSms);
login = (TextView) findViewById(R.id.login);
reset = (TextView) findViewById(R.id.reset);
} //弹窗确认
private void alterWarning(){
//先new出一个监听器,设置好监听
DialogInterface.OnClickListener dialogOnclicListener=new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
switch(which){
case Dialog.BUTTON_POSITIVE:
dialog.dismiss();
//通过sdk发送短信验证(请求获取短信验证码,在监听(eventHandle)中返回)
SMSSDK.getVerificationCode(country, phoneEdit.getText().toString());
//设置获取验证码按钮不能点击
getSms.setClickable(false);
//倒计时,执行次数为(TIME+1)*1000/1000,countDownTimer每次执行间隔:1000(单位为毫秒)
countDownTimer = new CountDownTimer((TIME+1)*1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
getSms.setText(TIME-- + "秒后再次获取验证码");
} @Override
public void onFinish() {
//设置获取验证码按钮可以点击
getSms.setClickable(true);
getSms.setText("点击获取短信验证码");
}
};
countDownTimer.start();
break;
case Dialog.BUTTON_NEGATIVE:
dialog.dismiss();
Toast.makeText(RegisterActivity.this, "已取消", Toast.LENGTH_SHORT).show();
break;
}
}
};
//dialog参数设置
AlertDialog.Builder builder=new AlertDialog.Builder(this); //先得到构造器
builder.setTitle("发送短信"); //设置标题
builder.setMessage("我们将把验证码发送到以下号码:\n"+country+"-"+phoneEdit.getText().toString()); //设置内容
builder.setIcon(R.drawable.icon);//设置图标,图片id即可
builder.setPositiveButton("确认",dialogOnclicListener);
builder.setNegativeButton("取消", dialogOnclicListener);
builder.create().show();
} //判断手机号码是否已注册过
public boolean isRegister(){
boolean isLogin = false;
。。。。。 return isLogin;
} }
『实践』Android之短信验证码(用的Mob短信验证)的更多相关文章
- 『记录』Android参考资料
欢迎留言推荐好的教程.资料.博客及作者等. 『记录』Android参考资料 1.前期环境 Android Studio使用Git Android Studio快捷键总结 Android Studio及 ...
- 『实践』Yalmip获取对偶函数乘子
『实践』Yalmip获取对偶函数乘子 一.sdpsetting设置 Yalmip网站给出的说明 savesolveroutput默认为0,需要设置为1才会保存输出结果. 下面是我模型的约束个数: 二. ...
- 『实践』Yalmip+Ipopt+Cplex使用手册
Yalmip+Ipopt+Cplex使用手册 1.软件版本 Cplex 12.6.2,Matlab R2014a,Ipopt 3.12.9,Yalmip 2.Cplex添加方法 官方下载地址: htt ...
- 『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现
『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现 1.基本设定和软件版本 主机名 ip 对应角色 mas ...
- 『BUG』Android Studio 64位 始终提示 JVM 启动不了,JDK配置失败,error code -1
前几天 安装了 Android Studio 2.2. 本来一切都好,但是当我修改了 配置文件 studio64.exe.vmoptions 想修改 最大内存(保证运行流畅)后,AS 就再也运行不了了 ...
- 『转』android官网翻译好的蓝牙API接口说明
Develop API Guides 连接 蓝牙 本文内容 基础知识 蓝牙权限 设置蓝牙 查找设备 查询配对的设备 发现设备 连接设备 连接为服务器 连接为客户端 管理连接 使用配置文件 供应商特定的 ...
- 『翻译』Android USB Host
USB Host When your Android-powered device is in USB host mode, it acts as the USB host, powers the b ...
- 『实践』百度地图给map添加右键菜单(判断是否为marker)
var map; var s;//经度 var w;//纬度 $(document).ready(function(){ $(".mune").load("jsp/c ...
- 『实践』Yalmip建模+Cplex类求解
Yalmip建模+Cplex类求解 一.缘由 Yalmip只能设置部分Cplex的参数,所以需要调用Cplex类.而且optimize是Yalmip提供的常用函数,但此函数的返回结果参数有限. 图1 ...
随机推荐
- (Alpha)Let's-个人贡献分
Alpha阶段个人贡献分如下: (1201)林珣玙 60 (1190)康家华 55 (1194)刘彦熙 53 (1168)仇栋民 48 (1183)马瑶华 42 (1222)张启东 42
- [转帖]Programmer’s guide to the big tech companies 💻
Programmer’s guide to the big tech companies
- PSP(3.16——3.22)以及周记录
3.17 13:30 14:45 15 60 讨论班 A Y min 14:50 17:05 5 130 得到设备 Cordova 蓝牙连接 A Y min 23:15 23:45 5 25 英语百词 ...
- OneZero第四周第四次站立会议(2016.4.14)
1. 时间: 15:00--15:10 共计10分钟. 2. 成员: X 夏一鸣 * 组长 (博客:http://www.cnblogs.com/xiaym896/), G 郭又铭 (博客:http ...
- Latex使用:在latex中添加算法模块
在Miktex下有三个latex algorithm包,分别为:algorithm,algorithmic,algorithm2e三个,其中algorithm,algorithmic经常成套使用: l ...
- BZOJ2753 SCOI2012滑雪与时间胶囊(最小生成树)
首先显然可以把所有能到的点拎出来建个新图,这样第一问也就做好了. 剩下的部分似乎是一个裸的最小树形图.但显然这个东西是没什么学的必要的并且不太能跑过去. 考虑建出来的图有什么性质.可以发现如果没有高度 ...
- 分布式为什么使用Redis
一 为什么使用 Redis 在项目中使用 Redis,主要考虑两个角度:性能和并发.如果只是为了分布式锁这些其他功能,还有其他中间件 Zookpeer 等代替,并非一定要使用 Redis. 性能: 如 ...
- 棋盘游戏 HDU - 1281 (删点 二分匹配)
小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,这当然很简单,但是Gardon限制了只有某些格子才可以放,小希还是很轻松的解决 ...
- 【Luogu P4074】[WC2013]糖果公园(树上带修改莫队)
题目描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 \(n\) 个游 ...
- 20145215《网络对抗》shellcode注入&Return-to-libc攻击深入
20145215<网络对抗>shellcode注入&Return-to-libc攻击深入 Shellcode注入 基础知识 Shellcode实际是一段代码,但却作为数据发送给受攻 ...