1、这里说下云之迅的实现原理,首先得去云之迅平台去申请个开发者账号,然后集成云之迅代码。
2、代码原理其实也很简单,就是自己在本地生成一个多少位的验证码,然后把验证码等参数通过云之迅的接口发给云之迅,再通过云之迅给那台手机发送短信验证码,然后得到验证码之后输入验证码,跟一开始生成的验证码进行对比,如果匹配的话就算是验证通过,当然也可以本地md5加密,当前demo是没有进行验证码加密的。
首先看下效果动图(由于隐私问题把电话号码挡住了一部分):
好了,下面我们进入正题!!!!
1、下面我们先看目录结构(红线部分就是云之迅的代码集成的部分,我们真正写的只有一个MainActivity)
2、好了,咱们来看看MainActivity这个里面的代码:
package com.wyw.smsdemo;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
// 确认按钮
private Button btn_enter;
// 发送验证码
private Button btn_send_code;
// 验证码输入框
private EditText edit_code;
// 手机号码输入框
private EditText edit_phone;
// 验证码
private String code;
/**
* 短信平台 Account sid
*/
public final static String SMS_SID = "";
/**
* 短信平台 Auth Token
*/
public final static String SMS_TOKEN = "";
/**
* 短信平台 SMS_APPID
*/
public final static String SMS_APPID = "";
/**
* 短信模板ID SMS_TEMPLATEID
*/
public final static String SMS_TEMPLATEID = "";
//计时器
private TimeCount timeCount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_enter = (Button) findViewById(R.id.btn_enter);
btn_send_code = (Button) findViewById(R.id.btn_send_code);
edit_code = (EditText) findViewById(R.id.edit_code);
edit_phone = (EditText) findViewById(R.id.edit_phone);
btn_enter.setOnClickListener(this);
btn_send_code.setOnClickListener(this);
}
/**
* 内部类计时器
*/
private class TimeCount extends CountDownTimer {
public TimeCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);// 参数依次为总时长,和计时的时间间隔
}
@Override
public void onFinish() {// 计时完毕时触发
btn_send_code.setText("重新发送验证码");
btn_send_code.setEnabled(true);
}
@Override
public void onTick(long millisUntilFinished) {// 计时过程显示
btn_send_code.setText((millisUntilFinished / 1000) + "后可重新发送验证码");
btn_send_code.setEnabled(false);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (timeCount!=null) {
timeCount.cancel();
}
}
@Override
public void onClick(View v) {
if (btn_enter == v) {//确认按钮
String code_lin = edit_code.getText().toString();
if (TextUtils.isEmpty(code_lin)) {
Toast.makeText(MainActivity.this, "验证码不能为空", Toast.LENGTH_SHORT).show();
return;
}
if (code != null && code.equals(code_lin)) {
Toast.makeText(MainActivity.this, "验证成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "验证失败,请填写正确的验证码", Toast.LENGTH_SHORT).show();
}
} else if (btn_send_code == v) {//发送验证码
if (TextUtils.isEmpty(edit_phone.getText().toString())) {
Toast.makeText(MainActivity.this, "手机号码不能为空", Toast.LENGTH_SHORT).show();
return ;
}
if (!isMobileNO(edit_phone.getText().toString())) {
Toast.makeText(MainActivity.this, "手机号码不合法", Toast.LENGTH_SHORT).show();
return ;
}
sendSMS();
}
}
/**
* 验证手机格式
*/
public static boolean isMobileNO(String mobiles) {
/*
移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
联通:130、131、132、152、155、156、185、186
电信:133、153、180、189、177(1349卫通)
总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9
*/
String telRegex = "[1][134578]\\d{9}";//"[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
if (TextUtils.isEmpty(mobiles)) {
return false;
} else {
return mobiles.matches(telRegex);
}
}
/**
* 发送短信验证码
*/
private void sendSMS() {
code = Math.round(Math.random() * 10000) + "";
if (code.length() > 4) {
code = code.substring(0, 4);
} else if (code.length() < 4) {
sendSMS();
return;
}
new Thread(new Runnable() {
public void run() {
JsonReqClient client = new JsonReqClient();
String result = client.sendVerificationCode(SMS_APPID, SMS_SID,SMS_TOKEN, code, edit_phone.getText().toString(), SMS_TEMPLATEID);
//{"resp":{"respCode":"000000","templateSMS":{"createDate":"20140820145658","smsId":"d2c49329f363b802fb3531d9c67b54f8"}}}
if (result != null && result.length() > 0) {
try {
JSONObject object = new JSONObject(result);
if (object.has("resp")) {
JSONObject item = object.getJSONObject("resp");
//Code = 105122 同一天同一用户不能发超过10条验证码(因运营商限制一般情况下不足5条)
if (item.has("respCode") && item.getString("respCode").equals("000000")) {
mHandler.sendEmptyMessage(0);
} else {
mHandler.sendEmptyMessage(1);
}
} else {
mHandler.sendEmptyMessage(1);
}
} catch (JSONException e) {
e.printStackTrace();
mHandler.sendEmptyMessage(1);
}
} else {
mHandler.sendEmptyMessage(1);
}
}
}).start();
}
private Handler mHandler = new Handler() {
@Override
public void dispatchMessage(Message msg) {
switch (msg.what) {
case 0:
Toast.makeText(MainActivity.this, "短信验证码发送成功", Toast.LENGTH_SHORT).show();
timeCount = new TimeCount(60000, 1000);
timeCount.start();
break;
case 1:
Toast.makeText(MainActivity.this, "短信验证码发送失败", Toast.LENGTH_SHORT).show();
break;
}
}
};
}
在代码里面我们可以看到这4个常量参数,然而这4个参数是怎么获取的呢?请往下看我会一一解释!
/**
* 短信平台 Account sid
*/
public final static String SMS_SID = "";
/**
* 短信平台 Auth Token
*/
public final static String SMS_TOKEN = "";
/**
* 短信平台 SMS_APPID
*/
public final static String SMS_APPID = "";
/**
* 短信模板ID SMS_TEMPLATEID
*/
public final static String SMS_TEMPLATEID = "";
首先是(短信平台 Account sid,短信平台 Auth Token)这2个参数,请看图中红色框框标出的部分,就可以知道咱们的这2个参数怎么获得,当然前提是你必须得有个开发者账号!!:
接着就是(短信平台 SMS_APPID)这个参数的获取了,这个参数呢你得先去“应用管理-应用列表”里面去把你的应用给添加起来,然后会出现个你的应用列表,然后点击该应用就能看到该下图:
最后这个参数呢(短信模板ID SMS_TEMPLATEID)也是在“应用管理-短信管理”里面有个创建短信模板的,请先创建短信的模板,我这里会跟你提供一个比较大众的模板,当然了如果有不知道模板的规则是怎样可以点击下图红框标记的查看规则说明。
当模板创建成功之后就得到咱们需要的(短信模板ID SMS_TEMPLATEID)这个参数啦!请看下图
<strong>短信平台 SMS_APPID这个参数在JsonReqClient这个类里面去配置json.put("templateId", "30562"); 151行</strong>
这样我们就拿到所有的参数了,然后调用上面代码的这段代码(原理也说了本地生成一个多少位的验证码,然后通过接口传给云之迅平台,由云之迅平台发送短信,收到短信后与本地做验证,当前也可以进行加密之后的验证):
/**
* 发送短信验证码
*/
private void sendSMS() {
code = Math.round(Math.random() * 10000) + "";
if (code.length() > 4) {
code = code.substring(0, 4);
} else if (code.length() < 4) {
sendSMS();
return;
}
new Thread(new Runnable() {
public void run() {
JsonReqClient client = new JsonReqClient();
String result = client.sendVerificationCode(SMS_APPID, SMS_SID,SMS_TOKEN, code, edit_phone.getText().toString(), SMS_TEMPLATEID);
//{"resp":{"respCode":"000000","templateSMS":{"createDate":"20140820145658","smsId":"d2c49329f363b802fb3531d9c67b54f8"}}}
if (result != null && result.length() > 0) {
try {
JSONObject object = new JSONObject(result);
if (object.has("resp")) {
JSONObject item = object.getJSONObject("resp");
//Code = 105122 同一天同一用户不能发超过10条验证码(因运营商限制一般情况下不足5条)
if (item.has("respCode") && item.getString("respCode").equals("000000")) {
mHandler.sendEmptyMessage(0);
} else {
mHandler.sendEmptyMessage(1);
}
} else {
mHandler.sendEmptyMessage(1);
}
} catch (JSONException e) {
e.printStackTrace();
mHandler.sendEmptyMessage(1);
}
} else {
mHandler.sendEmptyMessage(1);
}
}
}).start();
}