PS:最近很多事情都拖拖拉拉的..都什么办事效率啊!!! 还得吐槽一下移动运营商,验证码超过五次的时候,直接把我的手机号封闭.真是受够了.

学习笔记:

1.Android之如何获取短信验证码.

2.如何读取刚收到的短信的相关内容.

 现如今,验证码在Android的客户端还是非常普遍的.通过手机账号和验证码直接去注册应用账户的信息.很多应用都以这种方式来完成注册.简单的介绍一下吧.

 Android获取短信验证码还是比较简单的,通过Mob官网提供的ShareSDK,调用其中内部的方法,就可以获取到短信的验证码了.提供一下Mob的官网地址.http://www.mob.com/#/在官网上注册相关的信息之后,下载相关的jar包和.so文件就可以实现获取短信验证码了(2.0之前的版本都需要下载jar包和 .so文件,而现在的2.2版本已经不需要下载.so文件了,通过加载SMSSDK.jar,MobCommons.jar,MobTools.jar包就可以直接使用).如何注册我就不解释了.

 最后注册完的样式就是这样的..我们来看看具体实现..

1.如何获取短信验证码.

 i.首先需要初始化SDK,第三方这些东西首先必须要有的操作就是初始化SDK.一般都在OnCreate()函数中来完成.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
SMSSDK.initSDK(this, AppKey, APPSECRET);
EventHandler eh = new EventHandler() { @Override
public void afterEvent(int event, int result, Object data) {
Message msg = new Message();
msg.arg1 = event;
msg.arg2 = result;
msg.obj = data;
handler.sendMessage(msg);
} };
SMSSDK.registerEventHandler(eh);
}

这个是必须要进行的操作,否则后续的东西都将无法完成.initSDK(Context context,String AppKey,String AppSECRET),初始化需要传递Context对象,以及我们申请的Key和SECRET.并且这里定义了一个EventHandler,用来进行验证的时候将一些消息提供给主线程的Handler,让主线程来做一些相关的操作来通知用户验证的情况到底如何.

 ii.调用SMSSDK.getVerificationCode(String,String)方法

 初始化SDK之后,我们就可以通过使用getVerificationCode()方法来获取我们的验证码了.

/**
* @param string 电话号码的区号 比如说86
* @param string 具体的电话号码
*/
SMSSDK.getVerificationCode("86", PhoneEd.getText().toString());

我们在调用方法的时候,需要传递我们手机号码的区号和具体的手机号码.由于中国国内是86开头.因此传递的区号就是86,在加上自己的电话号码就可以通过网络调用方法来获取相关的验证码了.

 iii.验证我们输入的验证码和发送过来的验证码是一致的.

 当验证码发送过来的时候,客户端一般就需要进行输入,但是这里需要一个验证的过程,判断当前用户输入的验证码和发送过来的验证码是否一致.

SMSSDK.submitVerificationCode("86", phone, CodeEd.getText().toString());

验证的方式通过调用submitVerificationCode()方法来完成.需要传递区号,电话号码,以及我们输入的验证码的数值.验证的过程由ShareSDK帮我们完成.因此就不需要执行太多复杂的操作.当我们传递的数值和发送过来的数值是一样的,那么就会验证成功,否则就会验证失败.

 这样在我们的客户端软件上就可以通过这种验证方式来完成注册功能.当验证成功后,就可以进入新的界面,如果验证失败,那么就需要确认输入的验证码.这样就能够完成应用程序的验证码验证.

 一般情况下,我们只需要通过查看短信,然后提交相关的验证码就可以了,但是还有一些其他的应用更加的人性化,当验证码信息发送到手机内部的时候直接就能够获取到相关的验证码,然后直接添加在需要验证的地方,这样非常的方便,并且还能防止用户输入错误.那么这就涉及到读取短信的相关内容了.

 iv.添加相关的权限

    <uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

 那么如何获取短信的相关内容呢?

2.如何获取刚收到的短信的相关内容.

 一般而言,短信的验证是以新短信的方式直接发送给用户的,那么应用程序如果想到读取刚收到的短息内容,就需要有相关的监听事件.我通过使用ContentObserver来实现的.通过使用这个类可以捕捉特定的uri使数据库改变,然后进而作一些相关的处理.

 那么我们就可以这样去实现,通过继承ContentObserver类,重写内部的onChange方法,设置特定的Uri,使得我们的类能够监听短信数据发生了变化这样我们的应用程序就知道什么时候短信到来了.那么短信到来之后,我们通过对短信内容的获取,然后读取内容中的验证码信息就可以了.

private class SmsObserver extends ContentObserver {

        public SmsObserver(Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
}
/**
*Uri.parse("content://sms/inbox")表示对收到的短信的一个监听的uri.
*/
@Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
Cursor cursor = getContentResolver().query(
Uri.parse("content://sms/inbox"), null, null, null, null);
//这里不要使用while循环.我们只需要获取当前发送过来的短信数据就可以了.
cursor.moveToNext();
sb.append("body=" + cursor.getString(cursor.getColumnIndex("body"))); //获取短信内容的实体数据.
Pattern pattern = Pattern.compile("[^0-9]"); //正则表达式.
Matcher matcher = pattern.matcher(sb.toString());
CodeText = matcher.replaceAll("");
CodeEd.setText(CodeText); //将输入验证码的控件内容进行改变.
cursor.close(); //关闭游标指针.
super.onChange(selfChange);
}
}

实现类的方式如上,通过重写OnChange方法来进行后续的操作,这里的cursor可以对当前的短信数据库中的数据进行查找,这里的cursor指针不要使用while循环,因为验证码这条短信是随发即用的,我们也只需要获取当前发送过来的验证码短信中的相关内容,如果cursor使用了while循环,那么将会读取短信中的所有内容.这并不是我们想要的.

 当我们获取到了短信的具体内容之后,我们可以通过使用正则表达式,去匹配短信内容的数字,然后就能够获取到验证码数据了.大体的思路就是这样一个情况.同时我们需要添加相关用户权限.

 <uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />

 完成了上面的步骤之后,我们需要获取ContentResolver实例,然后注册ContentObserver。

getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new SmsObserver(new Handler()));

注册我们需要传递相关的uri,第二个参数决定匹配uri的方式,如果设置为true的话,那么表示不精确匹配,那么也就表示,如果是一类的uri,那么都会被匹配到,如果设置为false,那么也就只能匹配到我们传递进去的uri,也就是所谓的精确匹配.最后一个对象需要传递一个子类的实例,并且需要传递Handler对象.这样我们也就可以在这个方法里去更新ui了.

 当我们不需要使用ContentObserver的时候,我们只需要注销注册就可以了.

 相对而言,验证码信息一般都是内容比较少的,如果内容比较复杂,然后还有其他额外的数字信息,那么我们在使用正则表达式的时候同时需要进行相关的优化.

 最后上一个源代码:

package com.example.sms;

import java.util.regex.Matcher;
import java.util.regex.Pattern; import org.json.JSONObject; import cn.smssdk.EventHandler;
import cn.smssdk.SMSSDK;
import cn.smssdk.utils.SMSLog;
import android.app.Activity;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
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 getCode;
private Button Identity; private EditText PhoneEd;
private EditText CodeEd;
private String AppKey = "110ee66f30b40";
private String APPSECRET = "85ec67aed1b89e3ec73f37b8b89f5142";
public String phone; private String CodeText; private Handler handler = new Handler() { @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
int event = msg.arg1;
int result = msg.arg2;
Object data = msg.obj;
if (result == SMSSDK.RESULT_COMPLETE) {
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
Toast.makeText(getApplicationContext(), "提交验证码成功",
Toast.LENGTH_SHORT).show();
} else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) {
// 已经验证
Toast.makeText(getApplicationContext(), "验证码已经发送",
Toast.LENGTH_SHORT).show();
}
} else {
int status = 0;
try {
((Throwable) data).printStackTrace();
Throwable throwable = (Throwable) data; JSONObject object = new JSONObject(throwable.getMessage());
String des = object.optString("detail");
status = object.optInt("status");
if (!TextUtils.isEmpty(des)) {
Toast.makeText(MainActivity.this, des,
Toast.LENGTH_SHORT).show();
return;
}
} catch (Exception e) {
SMSLog.getInstance().w(e);
}
}
} }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
SMSSDK.initSDK(this, AppKey, APPSECRET);
EventHandler eh = new EventHandler() { @Override
public void afterEvent(int event, int result, Object data) {
Message msg = new Message();
msg.arg1 = event;
msg.arg2 = result;
msg.obj = data;
handler.sendMessage(msg);
} };
SMSSDK.registerEventHandler(eh);
} private void init() { getCode = (Button) findViewById(R.id.getCode);
Identity = (Button) findViewById(R.id.Indentity);
PhoneEd = (EditText) findViewById(R.id.PhoneEd);
CodeEd = (EditText) findViewById(R.id.Code);
getCode.setOnClickListener(this);
Identity.setOnClickListener(this);
} private class SmsObserver extends ContentObserver { public SmsObserver(Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
} @Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
Cursor cursor = getContentResolver().query(
Uri.parse("content://sms/inbox"), null, null, null, null);
cursor.moveToNext();
sb.append("body=" + cursor.getString(cursor.getColumnIndex("body"))); System.out.println(sb.toString());
Pattern pattern = Pattern.compile("[^0-9]");
Matcher matcher = pattern.matcher(sb.toString());
CodeText = matcher.replaceAll("");
CodeEd.setText(CodeText);
cursor.close();
super.onChange(selfChange);
}
} @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.getCode: // 获取验证码的过程.
if (!TextUtils.isEmpty(PhoneEd.getText().toString())) {
getContentResolver().registerContentObserver(
Uri.parse("content://sms"), true,
new SmsObserver(new Handler()));
SMSSDK.getVerificationCode("86", PhoneEd.getText().toString());
phone = PhoneEd.getText().toString(); } else {
Toast.makeText(MainActivity.this, "电话号码不能为空", Toast.LENGTH_LONG)
.show();
}
break;
case R.id.Indentity:
SMSSDK.submitVerificationCode("86", phone, CodeEd.getText()
.toString());
break;
}
} protected void onDestroy() {
SMSSDK.unregisterAllEventHandler();
getContentResolver().unregisterContentObserver(new SmsObserver(handler));
};
}

这样就能够完成一个简单的通过使用短信验证码的方式来实现验证,在一般的项目中,我们可以根据具体的需求进行相关的改良,总之万变不离其宗思路基本都是一样的.当然在判断是否有短信到来也可以使用BroadCaseReceiver来实现,不过我看了网上的一些相关的资源,自己也试了一下,没有实现出来.感觉没有ContentObserver这么简单方便.

 最后提供一个源代码下载:http://files.cnblogs.com/files/RGogoing/SMS.rar

 

Android学习笔记之短信验证码的获取和读取的更多相关文章

  1. 学习笔记7-Android短信发送器

    新建一个Android项目sns. 在String.xml添加文字 <resources> <stringname="app_name">Sns发送短信&l ...

  2. Android学习笔记_12_网络通信之从web获取资源数据到Android

    从web获取图片信息,并显示到android的imageView控件. 一.添加网络访问权限. <uses-permission android:name="android.permi ...

  3. Android之短信验证码

    我们今天所使用的方案仅仅是android手机设备集成短信验证码功能的方案之中的一个. 我们所採用的方案是使用聚合数据的短信验证sdk. 程序的界面例如以下所看到的: 实现步骤: 1.到聚合数据官网上申 ...

  4. vue_drf之实现短信验证码

    一.需求 1,需求 我们在做网站开发时,登录页面很多情况下是可以用手机号接收短信验证码,然后实现登录的,那我们今天就来做一做这一功能. 伪代码: 进入登录页面,点击短信登录 输入手机号码,点击获取验证 ...

  5. sharesdk短信验证码的集成

    在ShareSDK官网http://mob.com/注册并创建Android应用.申请APP_key,下载SDK等 根据官网开发文档导入SDK,目录结构如下 将以上文件按需放入Android Stud ...

  6. <自动化测试>之<自动获取手机短信验证码>

    第一次写博,最近解决了做自动化测试短信验证码自动获取填入的方法减少了脚本的人工干预,并非拦截短信,所以不存在安全警报提醒,拿出来分享给大家,有感兴趣的大家可以加Q1856100 目前在职测试开发,,写 ...

  7. SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能

    在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...

  8. Android学习笔记_19_广播接收者 BroadcastReceiver及其应用_窃听短信_拦截外拨电话

    一.广播接收者类型: 广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”. 普通广播是完全异步的,可以在同一时刻(逻辑上 ...

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

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 很多应用刚打开的时候,让我们输入手机号,通过短信验证码来登录该应用.那么,这个场景是怎么实现的呢?其实是很多开放平台提供了短信验证功能 ...

随机推荐

  1. Runtime消息传送

    person.h #import<Foundation/Foundation.h> @interfacePerson :NSObject + (void)eat; - (void)run: ...

  2. 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...

  3. 在Grunt task中集成Protractor

    Protractor是专为AngularJS应用程序编写的UI自动化测试框架.前端构建有很多构建工具,比如Grunt.Gulp等.一般我们会把这些构建工具作为集成集成的脚本执行工具.所以如果把Prot ...

  4. DNS 正向查找与反向查找

    原创地址:http://www.cnblogs.com/jfzhu/p/3996323.html 转载请注明出处 所谓正向查找,就是说在这个区域里的记录可以依据名称来查找对应的IP地址.反向查找就是在 ...

  5. java gc的考察

    参考http://www.cnblogs.com/mazj611/p/3481610.html 看了很多博客.书, 仍然有所不懂.很多看过即忘记.实在要不得. 我们可以通过jstat获取gc情况 js ...

  6. mvc项目controller重命名了,用原网页url访问不了了,怎么办?

    如题.MVC项目,手机网站. 公司的官方微信上,用户关注之后,点击相应菜单就可以使用相关的功能. 最近项目重构,有些不规范的命名方式给予了重构.上线后,微信上发现一些网页访问不了了. 联系微信的维护人 ...

  7. EF架构~关于多对多关系表无法更新与插入的问题

    回到目录 在EF里,我们设计模型时,会设计到多对多关系,在EF里会把这种关系会转成两个一对多的关系表,这是比较友好的,因为多对多来说,对于业务本身没什么意思,所以隐藏了,没什么坏处,但对于这个隐藏来说 ...

  8. PHP数据库操作:使用ORM

    之前我发了一篇博文PHP数据库操作:从MySQL原生API到PDO,向大家展示PHP是如何使用MySQL原生API.MySQLi面向过程.MySQLi面向对象.PDO操作MySQL数据库的.本文介绍如 ...

  9. Nodejs·构建web应用

    本篇的内容比较多..... 1 首先是从基本的Nodejs服务方面讲述前后端统一语言在web应用中的作用: 2 然后讲了web中基本的知识,从请求方法到路由.从查询字符串到Cookie和Session ...

  10. Atitit 常用比较复杂的图像滤镜 attilax大总结

    Atitit 常用比较复杂的图像滤镜 attilax大总结 像素画滤镜 水彩油画滤镜 素描滤镜 梦幻镜 特点是中央集焦,周围景物朦化微带光晕,使人产生如入梦境的感觉.常用于拍摄婚纱.明星照,也用于其它 ...