今天要实现的使用第三方平台获取验证码,值得高兴的是,完全免费哦,但是一个手机号12小时内只能发5条短信,我在录制视频时,已经将五条都用完了,于是找了他们的官方客服要了key和secret(客服很有耐心 点个赞)先看效果图:
眼尖的看客也许会发现,你的手机号码根本不符合格式的好哇,这其实是博主为了保护自己的隐私,提前把输入手机号的那一栏写死了,但实际上并不是用这个手机号发的(当然,发了也肯定收不到),接收验证码的手机号在程序内部已经写好了,实际使用中我们选择需要接收的手机号应该是从手机号的edittext中获取的。
先发一下这个平台的官网,有需要的可以自己去下载 ( 第三方平台官网:http://www.mob.com/)
好了,来说说实现这个功能的步骤,1、布局搭建; 2、集成环境(博主第一次集成失败,花了三四个小时都未能找到原因,所以虽然官网有集成步骤,但是我还是选择更详细的说明一下,只要集成对了,使用其实是非常非常简单的);3、页面中基本的逻辑实现;4、自然是发送验证码以及验证 验证码啦
一、布局实现
效果图:
代码:
xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingEnd="16dp" android:paddingStart="16dp"> android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:text="注册" android:textColor="#00A600" android:textSize="34sp" android:textStyle="bold"/> android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:text="手机号码" android:textSize="20sp"/> <EditText android:id="@+id/editPhoneNumber" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="16dp" android:hint="请输入手机号码" android:labelFor="@+id/editPhone" android:inputType="phone"/> android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="验证码" android:textSize="20sp"/> android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/editCode" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="16dp" android:imeActionId="@+id/login" android:imeOptions="actionDone" android:inputType="number" android:paddingEnd="80dp" android:paddingStart="0dp" android:hint="请输入验证码" android:labelFor="@+id/editCode" tools:ignore="InvalidImeActionId" android:paddingRight="80dp" android:paddingLeft="0dp" /> android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="密码" android:textSize="20sp"/> <EditText android:id="@+id/editPassword" android:hint="请输入密码" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="16dp" android:labelFor="@+id/editPwd" android:inputType="numberPassword"/>
第二部分:集成环境
1、下载sdk(去官网下载)
2、解压之后把这几个文件放入Project目录下的libs中
3、在Module的build.gradle里面将libs加入仓库(repositories):(这段话来自于官网)
repositories{ flatDir{ dirs 'libs' //就是你放aar的目录地址 } }
4、添加依赖
compile name:'SMSSDK-3.0.0',ext:'aar' compile name:'SMSSDKGUI-3.0.0',ext:'aar'
5、添加权限(为啥有这么多权限)
android:name="android.permission.INTERNET" />
android:name="android.permission.READ_CONTACTS" />
android:name="android.permission.READ_PHONE_STATE" />
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
android:name="android.permission.ACCESS_NETWORK_STATE" />
android:name="android.permission.ACCESS_WIFI_STATE" />
android:name="android.permission.RECEIVE_SMS" />
android:name="android.permission.READ_SMS" />
android:name="android.permission.GET_TASKS" />
android:name="android.permission.ACCESS_FINE_LOCATION" />
6、在Application节点下添加以下属性:
android:name="com.mob.MobApplication"
7、在Application节点下添加以下meta-data:(很重要的一步,当初博主就是没加这个,所以弄了很久都未能成功)
android:name="Mob-AppKey" android:value="你的key"/>
android:name="Mob-AppSecret" android:value="你的secret"/>
8、在使用验证码的程序中对key和secret进行注册
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); //注册key和secret MobSDK.init(RegisterActivity.this, "你的key", "你的secret"); initData(); initUI(); initEvent(); }
至此,集成完成,其实官网上还有加一个activity的步骤,那是官网自己设置好的gui,由于我是自己写的页面,所以activity可加可不加
第三部分:页面简单逻辑实现
1、edittext验证格式,依旧使用textwatcher实现
TextWatcher codeWatecher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { String code = editable.toString().trim(); if (!TextUtils.isEmpty(code)) { isCodeOk = true; } else { isCodeOk = false; } setButtonEnable(); } };
就贴一个吧,逻辑都一样,使用监听器之后可以在输入框改变时对改变的内容进行监控
2、注册按钮是否可以点击的实现,只有三个输入框格式都正确时,注册按钮才能够点击,代码很少,我就说一下逻辑吧,最后再贴出总代码,实现这个功能上一篇也有讲过,就是给三个输入框一个布尔值,然后在三个监听器中改变这个布尔,当三个都为真时,注册按钮就可以点击了
第四部分:获取验证码以及验证验证码
官方有帮助文档,但是我觉得写的略微简陋,大致思路是先注册回掉接口,然后再使用短信验证码接口,短信验证码接口中有三个函数,依次是获取支持发送验证码的国家列表,发送验证码,验证验证码,值得注意的是,这些函数在执行后都会发送消息,然后我们可以在回掉接口中捕获这些消息,进行我们自己的逻辑处理。列如,在调用发送验证码函数后,我们可以这里处理逻辑(提醒用户验证码已发送)
if (i == SMSSDK.EVENT_GET_VERIFICATION_CODE) { // Log.d("RegisterActivity","11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); //Log.d("RegisterActivity",""+i); // Toast.makeText(RegisterActivity.this,"验证码已送达",Toast.LENGTH_SHORT).show(); }其中的i就是result,也就是使用发送验证码函数后返回的消息,此外,这个回掉函数中的线程并非是主线程,所以需要使用runOnUiThread来改变ui 具体看代码
1、初始化回掉接口
EventHandler eventHandler = new EventHandler() { //初始化接
2、监听消息
@Override public void afterEvent(int i, int i1, Object o) { super.afterEvent(i, i1, o); //成功接收到验证码时提醒用户 if (i1 == SMSSDK.RESULT_COMPLETE) { if (i == SMSSDK.EVENT_GET_VERIFICATION_CODE) {//发送验证码函数被调用 // Log.d("RegisterActivity","11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); //Log.d("RegisterActivity",""+i); // Toast.makeText(RegisterActivity.this,"验证码已送达",Toast.LENGTH_SHORT).show(); } else if (i == SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES) { //支持发送验证码的国家列表方法被调用 //Toast.makeText(RegisterActivity.this, "验证码已送达", Toast.LENGTH_SHORT).show(); Log.d("RegisterActivity", "这个函数有执行:" + o); } else if (i == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {//提交验证码被调用 runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(RegisterActivity.this, "验证成功", Toast.LENGTH_LONG).show(); } }); } }
值得注意的是,只要是那三个函数被调用,就会触发回掉接口,说明白点就是,这个只是告诉你,”我调用是调用了,但是对不对我就不知道了,你就自己琢磨吧“,不过一般除了集成失败以外,还有你验证码发送数量超出限制(12小时5条,通过审核就是无限制的了),嗯,还有服务器的问题,一般都没啥问题(感觉越说问题越大)
下面是短信验证码的三个方法:
1、获取支持验证码国家的,我没用,因为我的号码是中国,那么中国的代号你们知道吗?没错,就是86
2、发送验证码的
SMSSDK.getVerificationCode("86", editPhoneNumber.getText().toString());第一个参数是国家代号,第二个是接收验证码的手机
3、验证验证码的,注释中有解释意义
//三个形参依次代表:国家代号、手机号、输入的验证码 SMSSDK.submitVerificationCode("86", editPhoneNumber.getText().toString(), editCode.getText().toString());至此,注册功能完成
总代码:
package com.everyday.wei.everyday.Acitivity; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.support.annotation.Nullable; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.everyday.wei.everyday.R; import com.mob.MobSDK; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import cn.smssdk.EventHandler; import cn.smssdk.SMSSDK; /** * Created by ikecin on 2017/12/4. */ public class RegisterActivity extends Activity { @BindView(R.id.editPhoneNumber) EditText editPhoneNumber; @BindView(R.id.editCode) EditText editCode; @BindView(R.id.buttonCode) Button buttonCode; @BindView(R.id.editPassword) EditText editPassword; @BindView(R.id.buttonRegister) Button buttonRegister; private Boolean isPhoneNumberOk; private Boolean isCodeOk; private Boolean isPasswordOk; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); MobSDK.init(RegisterActivity.this, "你的key", "你的secret"); initData(); initUI(); initEvent(); } private void initEvent() { //绑定监听器 editPhoneNumber.addTextChangedListener(phoneNumberWatcher); editPassword.addTextChangedListener(passwordWatecher); editCode.addTextChangedListener(codeWatecher); } private void initUI() { } //初始数据 private void initData() { //初始注册按钮无法点击 isPhoneNumberOk = false; isCodeOk = false; isPasswordOk = false; buttonRegister.setEnabled(false); } //设置注册按钮是否可以点击 private void setButtonEnable() { if (isPasswordOk & isCodeOk & isPhoneNumberOk) { buttonRegister.setEnabled(true); buttonRegister.setBackgroundColor(Color.parseColor("#00BB00")); buttonRegister.setTextColor(Color.parseColor("#FFFFFF")); } else { buttonRegister.setEnabled(false); buttonRegister.setBackgroundColor(Color.parseColor("#E0E0E0")); } } @OnClick(R.id.buttonCode) public void onButtonCodeClicked() { sendCode(); //SMSSDK.getSupportedCountries(); SMSSDK.getVerificationCode("86", editPhoneNumber.getText().toString()); } private void sendCode() { EventHandler eventHandler = new EventHandler() { //初始化接口 @Override public void afterEvent(int i, int i1, Object o) { super.afterEvent(i, i1, o); //成功接收到验证码时提醒用户 if (i1 == SMSSDK.RESULT_COMPLETE) { if (i == SMSSDK.EVENT_GET_VERIFICATION_CODE) {//发送验证码函数被调用 // Log.d("RegisterActivity","11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); //Log.d("RegisterActivity",""+i); // Toast.makeText(RegisterActivity.this,"验证码已送达",Toast.LENGTH_SHORT).show(); } else if (i == SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES) { //支持发送验证码的国家列表方法被调用 //Toast.makeText(RegisterActivity.this, "验证码已送达", Toast.LENGTH_SHORT).show(); Log.d("RegisterActivity", "这个函数有执行:" + o); } else if (i == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {//提交验证码被调用 runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(RegisterActivity.this, "验证成功", Toast.LENGTH_LONG).show(); } }); } } } }; //注册监听器 SMSSDK.registerEventHandler(eventHandler); } @OnClick(R.id.buttonRegister) public void onButtonRegisterClicked() { //三个形参依次代表:国家代号、手机号、输入的验证码 SMSSDK.submitVerificationCode("86", editPhoneNumber.getText().toString(), editCode.getText().toString()); } //监听手机号码格式是否正确 TextWatcher phoneNumberWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { String inputStr = editable.toString().trim(); if (!TextUtils.isEmpty(inputStr) && inputStr.getBytes().length == 11) { isPhoneNumberOk = true; } else { isPhoneNumberOk = false; } setButtonEnable(); } }; //监听验证码格式是否正确 TextWatcher codeWatecher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { String code = editable.toString().trim(); if (!TextUtils.isEmpty(code)) { isCodeOk = true; } else { isCodeOk = false; } setButtonEnable(); } }; //监听密码是否正确 TextWatcher passwordWatecher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { String inputStr = editable.toString().trim(); if (!TextUtils.isEmpty(inputStr) && inputStr.getBytes().length >= 6) { isPasswordOk = true; } else { isPasswordOk = false; } setButtonEnable(); } }; }
需要提醒的是,为了保护隐私,我把程序中出现的key和secret都换成了“你的key”"你的secret",不要傻乎乎的直接写上去,程序运行不了还不知道错在哪里,说到这个,我小时候班上还真有人在抄答案的时候把“此题无参考答案”抄了上去,至于key和secret的来源是官网,注册之后随便创个项目名字就有了
反思和总结:
1、短信验证码还是比较简单,第三方平台也很良心,(我想起了某聚,说好的免费数据竟然一个号只能使用一个)
2、这个页面的功能实际并未完全实现,用户注册后我们肯定要存储用户数据的,至于存储方式,我先前说过使用sqlite(不会后台的伤),我的目标是安卓全栈,不过现在还是老老实实的增加安卓的深度
3、下一篇讲数据库的使用吧,see you
补充一:为了避免内存泄露,我们在onDestroy函数中应该注销我们创建的eventHandler,很重要的一点
补充二(2018.4.24):key和secret只需要注册一次 可以在manifest中注册 也可以在需要使用短信注册码中的活动中注册 另外 官网推出了3.0的注册方式 比本文介绍的要省去了很多步骤