Android接受验证码自动填入功能(源码+已实现+可用+版本兼容)
实际应用开发中,会经常用到短信验证的功能,这个时候如果再让用户就查看短信.然后再回到界面进行短信的填写,难免有多少有些不方便,作为开发者.本着用户至上的原则我们也应该来实现验证码的自动填写功能,还有一个重要的原因是为了防止恶意注册。今天实现这个功能的方法是用的广播来实现的
首先在AndroidMainfest.xml中加入所需要的权限:
<!-- 短信验证登陆功能需要添加次权限来自动填充验证码,用不到可以去掉 -->
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
首先看一下实现的效果,没效果说再多都没用,亲眼看到的才知道适不适合自己
中效果看完接下来就看怎么实现的了,这里使用的广播为动态注册,因为这个APP在进程杀死之后就不需要监听这个广播了,在Activity的onDestory之后注销广播。
SMSBroadcastReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log; import java.text.SimpleDateFormat;
import java.util.Date; /**
* Created by dingchao on 2018/3/31.
*/ public class SMSBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "SMSBroadcastReceiver"; private static MessageListener mMessageListener; public SMSBroadcastReceiver() {
super();
} @Override
public void onReceive(Context context, Intent intent) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for (Object pdu : pdus) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
String sender = smsMessage.getDisplayOriginatingAddress();
String content = smsMessage.getMessageBody();
long date = smsMessage.getTimestampMillis();
Date timeDate = new Date(date);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = simpleDateFormat.format(timeDate); Log.e(TAG, "onReceive: 短信来自:" + sender);
Log.e(TAG, "onReceive: 短信内容:" + content);
Log.e(TAG, "onReceive: 短信时间:" + time); if(content.indexOf("优铺")>-1){
mMessageListener.OnReceived(content);
}
// //如果短信号码来自自己的短信网关号码
// if ("your sender number".equals(sender) && mMessageListener != null) {
// Log.i(TAG, "onReceive: 回调");
// mMessageListener.OnReceived(content);
// }
}
} // 回调接口
public interface MessageListener { /**
* 接收到自己的验证码时回调
*
* @param message 短信内容
*/
void OnReceived(String message);
} /**
* 设置验证码接收监听
*
* @param messageListener 自己验证码的接受监听,接收到自己验证码时回调
*/
public void setOnReceivedMessageListener(MessageListener messageListener) {
this.mMessageListener = messageListener;
}
}
MainActivity.java
import android.Manifest;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley; import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import static android.R.attr.phoneNumber; public class MainActivity extends AppCompatActivity {
private EditText et_phone, et_code;
private Button btn_code;
private static final int REQUEST_PERMISSION_CODE = 0;
SMSBroadcastReceiver mSMSBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //实例化IntentFilter对象
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
mSMSBroadcastReceiver = new SMSBroadcastReceiver();
//注册广播接收
registerReceiver(mSMSBroadcastReceiver,filter); mSMSBroadcastReceiver.setOnReceivedMessageListener(new SMSBroadcastReceiver.MessageListener() {
public void OnReceived(String message) {
Log.e("tag", "1=" + message);
et_code.setText(getDynamicPwd(message));//截取6位验证码
}
}); et_phone = (EditText) findViewById(R.id.et_phone);
et_code = (EditText) findViewById(R.id.et_code);
btn_code = (Button) findViewById(R.id.btn_code);
btn_code.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getCode(et_phone.getText().toString());
}
}); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_PERMISSION_CODE);
} /* SMSBroadcastReceiver mSMSBroadcastReceiver = new SMSBroadcastReceiver();
mSMSBroadcastReceiver.setOnReceivedMessageListener(new SMSBroadcastReceiver.MessageListener() {
public void OnReceived(String message) {
Log.e("tag", "1=" + message);
et_code.setText(getDynamicPwd(message));//截取6位验证码
}
});*/ } /*发送验证码请求*/
private void getCode(final String phone) {
Log.e("getCode", "getCode:229:" + phoneNumber);
RequestQueue mQueue = Volley.newRequestQueue(MainActivity.this);
StringRequest strinRequest = new StringRequest(Request.Method.POST, "你的验证码请求接口", new Response.Listener<String>() {
@Override
public void onResponse(String s) {
Log.e("login", "-------获取到的idjson--------" + s.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) { }
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("phoneNumber", phone);
Log.e("map", "map:249:" + phone);
return map;
}
};
/*设置请求一次*/
strinRequest.setRetryPolicy(
new DefaultRetryPolicy(
500000,//默认超时时间,应设置一个稍微大点儿的,例如本处的500000
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,//默认最大尝试次数
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
)
);
mQueue.add(strinRequest);/*请求数据*/
} /*高版本手动获取权限*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_CODE) {
if (grantResults.length != 0) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "您阻止了app读取您的短信,您可以自己手动输入验证码", Toast.LENGTH_SHORT).show();
}
} else {
Log.e("TAG", "获取权限"); }
}
} /**
* 从字符串中截取连续6位数字组合 ([0-9]{6})截取六位数字 进行前后断言不能出现数字 用于从短信中获取动态密码
*
* @param content 短信内容
* @return 截取得到的6位动态密码
*/
public String getDynamicPwd(String content) {
// 此正则表达式验证六位数字的短信验证码
Pattern pattern = Pattern.compile("(?<![0-9])([0-9]{6})(?![0-9])");
Matcher matcher = pattern.matcher(content);
String dynamicPwd = "";
while (matcher.find()) {
dynamicPwd = matcher.group();
Log.i("TAG", "getDynamicPwd: find pwd=" + dynamicPwd);
}
return dynamicPwd;
} @Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mSMSBroadcastReceiver);
mSMSBroadcastReceiver = null;
}
}
主要的步骤代码已经贴出,源码地址链接:https://pan.baidu.com/s/1vbYxHZxw9t0LGF_BkzmpvQ 密码:fxrm
有问题或建议请联系dingchao7323@qq.com
Android接受验证码自动填入功能(源码+已实现+可用+版本兼容)的更多相关文章
- IntelliJ IDEA创建文件时自动填入作者时间 定制格式
IntelliJ IDEA创建文件时自动填入作者时间 定制格式 学习了:https://blog.csdn.net/Hi_Boy_/article/details/78205483 学习了:http: ...
- Android 全面插件化 RePlugin 流程与源码解析
转自 Android 全面插件化 RePlugin 流程与源码解析 RePlugin,360开源的全面插件化框架,按照官网说的,其目的是“尽可能多的让模块变成插件”,并在很稳定的前提下,尽可能像开发普 ...
- Android精品资源汇总,10个源码(持续更新)
最近一直在学习Android,在各大社区逛,总结下自己看到的一些不错的源码.希望可以给大家带来帮助. 1.Android精品源码:带动态效果的Button(按钮) 最喜欢各种效果的按钮了,没办法就是这 ...
- android版高仿淘宝客户端源码V2.3
android版高仿淘宝客户端源码V2.3,这个版本我已经更新到2.3了,源码也上传到源码天堂那里了,大家可以看一下吧,该应用实现了我们常用的购物功能了,也就是在手机上进行网购的流程的,如查看产品(浏 ...
- 【转载】Android异步消息处理机制详解及源码分析
PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...
- Android斗地主棋牌游戏牌桌实现源码下载
本次给大家分享下Android斗地主棋牌游戏牌桌实现源码下载如下: 为了节约内存资源,每张扑克牌都是剪切形成的,当然这也是当前编程的主流方法. 1.主Activity package com.biso ...
- android 在线升级借助开源中国App源码
android 在线升级借助开源中国App源码 http://www.cnblogs.com/luomingui/p/3949429.html android 在线升级借助开源中国App源码分析如下: ...
- Android 图片加载框架Glide4.0源码完全解析(二)
写在之前 上一篇博文写的是Android 图片加载框架Glide4.0源码完全解析(一),主要分析了Glide4.0源码中的with方法和load方法,原本打算是一起发布的,但是由于into方法复杂性 ...
- QQ2008自动聊天精灵delphi源码
QQ2008自动聊天精灵delphi源码 unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Grap ...
随机推荐
- 【CF245H】Queries for Number of Palindromes(回文树)
[CF245H]Queries for Number of Palindromes(回文树) 题面 洛谷 题解 回文树,很类似原来一道后缀自动机的题目 后缀自动机那道题 看到\(n\)的范围很小,但是 ...
- POJ1743:Musical Theme
题目 vjudge Sol 先差分 然后求不可重叠最长重复子串 bits/stdc++.h会CE # include <bits/stdc++.h> # define IL inline ...
- centos6.5下 hdp-2.4.2安装
(1)准备工作 /usr/sbin/sestatus -v getenforce1./usr/sbin/sestatus -v ##如果SELinux status参数为enabled即为开启状态SE ...
- HTTP架构介绍(2) 缓存
web缓存是自动复制所请求数据并将其保存在本地存储中的设备. 通过这样做, 可以实现: 减少网络流量 消除网络瓶颈 防止服务器超载 减少长距离的响应延迟 因此, 您可以清楚地说, web 缓存可提高用 ...
- Appserv(Apache) 配置ssl证书
一:打开httpd.conf文件,移除注释的行: Include conf/extra/httpd-ahssl.conf LoadModule ssl_module modules/mod_ssl.s ...
- Java Swing应用程序JLable超链接
在HTML中设置一个超链接是很容易的,使用<a></a>标签就可以完成了. 在客户端应用程序中,并没有这样的标签,但是可以使用按钮来实现,But 有时候就是想好看一点,不想要按 ...
- AJAX学习笔记2:XHR实现跨域资源共享(CORS)以及和JSONP的对比----转载
1 前言: 首先对参考文章作者表示感谢,你们的经验总结给我们这些新手提供了太多资源.本文致力于解决AJAX的CORS问题,我在逻辑上进行了梳理:首先,系统的总结了CORS问题的起源-同源策略:其次,介 ...
- 问题排查:The requested URL /test/index.jsp was not found on this server
问题描述 添加一个新模块,部署在服务器上.服务器上还部署有其他模块且访问正常,新模块和其他模块共用同一个域名.服务部署之后,请求如下: http://my.domain.com/test/index. ...
- SSM 使用 mybatis 分页插件 pagehepler 实现分页
使用分页插件的原因,简化了sql代码的写法,实现较好的物理分页,比写一段完整的分页sql代码,也能减少了误差性. Mybatis分页插件 demo 项目地址:https://gitee.com/fre ...
- MYSQL汇总
一.1.1 MYSQL 一.1.1.1 基础特性 1)性能卓越,服务稳定,很少出现异常宕机: 2)开放源代码且无版权制约,自主性强,使用成本低: 3)历史悠久,社区及用户非常活跃,遇到问题,可快速获得 ...