Android实现验证码

效果图

Github地址

地址:https://github.com/kongqw/Android-CheckView

使用

<kong.qingwei.demo.kqwcheckviewdemo.CheckView
android:id="@+id/checkView"
android:layout_width="200dp"
android:layout_height="50dp"
kongqw:bg_color="#FFFFFF00"
kongqw:line_num="10"
kongqw:point_num="100"
kongqw:text_length="6"
kongqw:text_size="30dp" />

设置验证码宽度

android:layout_width="200dp"

设置验证码高度

android:layout_height="50dp"

设置验证码背景颜色

kongqw:bg_color="#FFFFFF00"

设置验证码线的条数

kongqw:line_num="10"

设置验证码点的个数

kongqw:point_num="100"

设置验证码长度

kongqw:text_length="6"

设置验证码字符大小

kongqw:text_size="30dp"

验证码的类

package kong.qingwei.demo.kqwcheckviewdemo;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Toast; /**
* Created by kongqw on 2015/10/23.
*/
public class CheckView extends View {
Context mContext;
String mCheckCode = null;
Paint mTempPaint = new Paint();
private final int mPointNum;
private final int mLineNum;
private final int mTextLength;
private final float mTextSize;
// private final int mTextColor;
private final int mBgColor; // 验证码
public CheckView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CheckView);
// 获取随机点的个数
mPointNum = a.getInteger(R.styleable.CheckView_point_num, 0);
// 获取随机线的条数
mLineNum = a.getInteger(R.styleable.CheckView_line_num, 0);
// 获取验证码长度
mTextLength = a.getInteger(R.styleable.CheckView_text_length, 4);
// 获取验证码字体大小
mTextSize = a.getDimension(R.styleable.CheckView_text_size, 30);
// 获取验证码字体颜色
// mTextColor = a.getColor(R.styleable.CheckView_text_color, 0XFFFFFFFF);
// 获取背景颜色
mBgColor = a.getColor(R.styleable.CheckView_bg_color, 0XFFFFFFFF);
a.recycle(); mTempPaint.setAntiAlias(true);
mTempPaint.setTextSize(mTextSize);
mTempPaint.setStrokeWidth(3);
// Log.d("CheckView", "point_num = " + mPointNum);
// Log.d("CheckView", "line_num = " + mLineNum);
// Log.d("CheckView", "text_length = " + mTextLength);
// Log.d("CheckView", "text_color = " + mTextColor);
// Log.d("CheckView", "text_size = " + mTextSize);
// Log.d("CheckView", "bg_color = " + mBgColor);
} public void onDraw(Canvas canvas) {
// 生成验证码
mCheckCode = makeCheckCode();
// 设置二维码背景色
canvas.drawColor(mBgColor); final int height = getHeight();
// 获得CheckView控件的高度
final int width = getWidth();
// 获得CheckView控件的宽度
int dx = width / mTextLength / 2; char[] checkNum = mCheckCode.toCharArray();
for (int i = 0; i < mTextLength; i++) {
// 绘制验证控件上的文本
canvas.drawText("" + checkNum[i], dx, getPositon(height), mTempPaint);
dx += width / (mTextLength + 1);
}
int[] line;
for (int i = 0; i < mLineNum; i++) {
// 划线
line = getLine(height, width);
canvas.drawLine(line[0], line[1], line[2], line[3], mTempPaint);
}
// 绘制小圆点
int[] point;
for (int i = 0; i < mPointNum; i++) {
// 画点
point = getPoint(height, width);
canvas.drawCircle(point[0], point[1], 1, mTempPaint);
}
} /**
* 生成新的验证码
*/
public void invaliChenkCode() {
invalidate();
} public String getCheckCode() {
return mCheckCode;
} /**
* 产生随机验证码
*
* @return
*/
public String makeCheckCode() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < mTextLength; i++) {
int temp = (int) (Math.random() * 10);
sb.append(temp);
}
return sb.toString();
} /**
* 计算验证码的绘制y点位置
*
* @param height 传入CheckView的高度值
* @return
*/
public int getPositon(int height) {
int tempPositoin = (int) (Math.random() * height);
if (tempPositoin < 50) {
tempPositoin += 50;
}
return tempPositoin;
} /**
* 随机产生划线的起始点坐标和结束点坐标
*
* @param height 传入CheckView的高度值
* @param width 传入CheckView的宽度值
* @return 起始点坐标和结束点坐标
*/
public static int[] getLine(int height, int width) {
int[] tempCheckNum = {0, 0, 0, 0};
for (int i = 0; i < 4; i += 2) {
tempCheckNum[i] = (int) (Math.random() * width);
tempCheckNum[i + 1] = (int) (Math.random() * height);
}
return tempCheckNum;
} /**
* 随机产生点的圆心点坐标
*
* @param height 传入CheckView的高度值
* @param width 传入CheckView的宽度值
* @return
*/
public static int[] getPoint(int height, int width) {
int[] tempCheckNum = {0, 0, 0, 0};
tempCheckNum[0] = (int) (Math.random() * width);
tempCheckNum[1] = (int) (Math.random() * height);
return tempCheckNum;
}
}

测试类

package kong.qingwei.demo.kqwcheckviewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; public class MainActivity extends Activity implements View.OnClickListener {
private CheckView mCheckView;
private EditText mEditPass;
private Button mSubmit;
private Button mRef;
// 验证码:
private String mCheckCode = null; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化控件
mCheckView = (CheckView) findViewById(R.id.checkView);
mEditPass = (EditText) findViewById(R.id.checkTest);
mSubmit = (Button) findViewById(R.id.submit);
mRef = (Button) findViewById(R.id.ref);
mSubmit.setOnClickListener(this);
mRef.setOnClickListener(this); // 生成验证码
mCheckView.invaliChenkCode();
} public void onClick(View v) {
switch (v.getId()) {
case R.id.submit:
if (mEditPass.getText().toString().equals(mCheckView.getCheckCode())) {
Toast.makeText(this, "通过", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "未通过", Toast.LENGTH_SHORT).show();
}
break;
case R.id.ref:
// 生成新的验证码
mCheckView.invaliChenkCode();
break;
default:
break;
}
}
}

XML布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:kongqw="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <kong.qingwei.demo.kqwcheckviewdemo.CheckView
android:id="@+id/checkView"
android:layout_width="200dp"
android:layout_height="50dp"
kongqw:bg_color="#FFFFFF00"
kongqw:line_num="10"
kongqw:point_num="100"
kongqw:text_length="6"
kongqw:text_size="30dp" /> <EditText
android:id="@+id/checkTest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请出入验证码" /> <Button
android:id="@+id/submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="验证" /> <Button
android:id="@+id/ref"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="换一张" /> </LinearLayout>

Android下实现手机验证码的更多相关文章

  1. Android Studio使用Mob来获取手机验证码的源码

    本文来自:CSDN 感谢作者:qq_35812301(其实就是我的号!) 查看原文:http://blog.csdn.net/qq_35812301/article/details/79150775 ...

  2. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

  3. Android下 使用百度地图sdk

    百度地图 Android SDK是一套基于Android 2.1(v1.3.5及以前版本支持android 1.5以上系统)及以上版本设备的应用程序接口.可以使用该套 SDK开发适用于Android系 ...

  4. paip.突破 网站 手机 验证码 的 破解 总结

    paip.突破 网站 手机 验证码 的 破解 总结  作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn ...

  5. Web程序员开发App系列 - 调试Android和IOS手机代码(补图)

    Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...

  6. android下的数据存储

    android下数据存储的几种方式:(简单讨论) 1.文件 举例:登陆时“记住密码” 因为是基于Linux系统,直接建文件,文件会出现在项目工程:而手机登陆时,应该把文件放在手机里,通常数据放在dat ...

  7. C#发送手机验证码

    C#发送手机验证码,平台有很多,我就说说其中的1个平台 测试环境:.net2.0 测试效果:速度还可以,10秒内接收短信 1.去http://www.yuntongxun.com注册,会送8元测试金额 ...

  8. Android下的Linux指令集

    Android目录结构 data app:用户安装的应用 data:应用的专属文件夹 system:系统的配置信息,注册表文件 anr:anr异常的记录信息 dev:devices的缩写 存放设备所对 ...

  9. Android 下使用tcpdump网络抓包方法

    Android 下使用tcpdump网络抓包方法 抓包需要tcpdump以及Root权限,tcpdump在本文后有下载. 首先把tcpdump传进手机,用adb命令(放SD卡有时会有问题,我一次可以用 ...

随机推荐

  1. Python数据类型深入学习之字符串

    一. Python字符串 1. 下面来看一下python中常见字符串常量和表达式: Python中用来编写字符串的方法有以下几种: (1) 单引号:'speade' (2) 双引号:"spe ...

  2. org.apache.commons.lang3.tuple.Pair 作为更新参数,XML 中的 Sql 取不到值、报错

    项目用的 Mybatis,今天改一个需求,落地实现是批量更新,且只需要根据主键(id)来更新一个字段(name). 于是,没有犹豫,像下面这样设计了数据结构: 既然是批量更新,那外层肯定是 List ...

  3. [Luogu 3919]【模板】可持久化数组(可持久化线段树/平衡树)

    Description 如题,你需要维护这样的一个长度为 N 的数组,支持如下几种操作 在某个历史版本上修改某一个位置上的值 访问某个历史版本上的某一位置的值 此外,每进行一次操作(对于操作2,即为生 ...

  4. 【JZOJ4307】喝喝喝

    Description solution 正解:尺取法. 很容易想到尺取法,维护左右指针,\(a[i]\%a[j]==K\),当且仅当 \(a[j]>K\) 并且 \(a[i]-K\) 的约数中 ...

  5. [BZOJ]1050 旅行comf(HAOI2006)

    图论一直是小C的弱项,相比其它题型,图论的花样通常会更多一点,套路也更难捉摸. Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权 ...

  6. 作为开发也要了解的 mysql 优化思路

    作为开发人员,数据库知识掌握的可能不是很深入,但是一些基本的技能还是要有时间学习一下的.作为一个数据库菜鸟,厚着脸皮来总结一下 mysql 的基本的不能再基本的优化方法. 为了更好的说明,我假想出来了 ...

  7. 开发者说 | 使用Visual Studio Code编译、调试Apollo项目

    转载地址:https://mp.weixin.qq.com/s?__biz=MzI1NjkxOTMyNQ==&mid=2247484266&idx=1&sn=d6bcd4842 ...

  8. python类库numpy中常见函数的用法

    1. numpy.reshape  重塑 reshape是一种函数,函数可以重新调整矩阵的行数.列数.维数. B = reshape(A,m,n) 返回一个m*n的矩阵B, B中元素是按列从A中得到的 ...

  9. vim的基本介绍

    vim四种模式: 1.正常模式(Normal-mode) 当我们打开vim时就会进入到正常模式,这个时候是不能编辑的,一般用于浏览文件,包括复制,删除一些文本操作.我们可以通过键盘的上下左右来进行光标 ...

  10. Cisco 的基本配置实例之四----vlan的规划及配置(接入交换机)

    4.2 接入交换机的相关配置 ## 在此例中,我们联入的是一台接入交换机,此交换机的gi0/1口上联至核心交换机.也就意味着我们需要配置gi0/1为trunk口.具体的配置如下: D-2960-3(c ...