手势密码(四)

2024-08-31 23:38
文章标签 密码 手势

本文主要是介绍手势密码(四),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前写过3篇手势密码的demo,不过没有集成到真实的企业项目中,这几天正好领到一个手势密码项目,昨天刚好弄完,今天抽空整理下,目前还没有完善,有一些地方需要更改,不过基本的流程都可以跑通了

源码下载地址。。。。。



先看主界面的入口把、里面有2个button(一个是设置手势密码、一个是校验手势密码)

activity_main.xml

<RelativeLayout 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"tools:context="com.example.gesturelock.MainActivity" ><Buttonandroid:id="@+id/setting"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_alignParentTop="true"android:text="设置" /><Buttonandroid:id="@+id/verify"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:layout_toRightOf="@+id/setting"android:text="校验" /></RelativeLayout>
在看主界面的代码把

MainActivity

package com.example.gesturelock;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {private Button setting, verify;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);setting = (Button) findViewById(R.id.setting);verify = (Button) findViewById(R.id.verify);setting.setOnClickListener(this);verify.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.setting:startActivity(new Intent(this, GestureEditActivity.class));break;case R.id.verify:startActivity(new Intent(this, GestureVerifyActivity.class));break;default:break;}}}

想了想还是先贴数据库把---就是存放手势密码、以及还可以输入的手势密码次数

publicSQLiteOpenHelper

package com.example.gesturelock;import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class publicSQLiteOpenHelper extends SQLiteOpenHelper{private static String name = "publicsqlite";private static String GESTURE_PASSWORD = "gesture_password";private static final int version = 1;public SQLiteDatabase db;public publicSQLiteOpenHelper(Context context) {super(context, name, null, version);}@Overridepublic void onCreate(SQLiteDatabase db) {String sqlpass = "create table " + "gesture_password"+ "("+ GesturePassword.WXID + " text not null,"+ GesturePassword.PASSWORD + " text not null,"+ GesturePassword.REMAINOPPORTUNITY + " text not null)";db.execSQL(sqlpass);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("DROP TABLE IF EXISTS password");onCreate(db); }public class GesturePassword  {public static final String WXID = "wxid";public static final String PASSWORD = "password";public static final String REMAINOPPORTUNITY = "remainopportunity";}/*** 插入手势密码表*/public void insertGestureInfo(SQLiteDatabase database ,String password,String times){ContentValues values = null;try {values = new ContentValues();values.put(GesturePassword.WXID, "001");values.put(GesturePassword.PASSWORD, password);values.put(GesturePassword.REMAINOPPORTUNITY, ""+times);database.insert(publicSQLiteOpenHelper.GESTURE_PASSWORD, null,values);} catch (Exception e) {e.printStackTrace();throw new SQLException(e.getMessage());}finally{if (values != null) {values.clear();values = null;}}}/*** 修改手势密码表---初始化次数为8次* * */public void updateGestureInfo(SQLiteDatabase database,String password,String times) {ContentValues values = null;try {if (password == null) {values = new ContentValues();values.put(GesturePassword.WXID, "001");values.put(GesturePassword.REMAINOPPORTUNITY, ""+times);database.update(publicSQLiteOpenHelper.GESTURE_PASSWORD,values, "WXID=?",new String[] { "001" });}else {values = new ContentValues();values.put(GesturePassword.WXID, "001");values.put(GesturePassword.PASSWORD, password);values.put(GesturePassword.REMAINOPPORTUNITY, ""+times);database.update(publicSQLiteOpenHelper.GESTURE_PASSWORD,values, "WXID=?",new String[] { "001" });}} catch (SQLException e) {} finally {if (values != null) {values.clear();values = null;}}}/*** 查询手势密码表有无记录* @return*/public boolean queryGestureTableCount(SQLiteDatabase database){Cursor cursor = null;try {cursor = database.query(publicSQLiteOpenHelper.GESTURE_PASSWORD, null, null, null, null, null, null);if (cursor != null && cursor.getCount()>0) {return true;}else {return false;}} catch (Exception e) {}finally{if (cursor != null) {cursor.close();cursor = null;}}return false;}/*** 查询手势密码表--查看剩余次数* */public String queryGestureTime(SQLiteDatabase database) {Cursor cursor = null;try {cursor = database.query(publicSQLiteOpenHelper.GESTURE_PASSWORD, null, null, null, null, null, null);if ((cursor != null) && (cursor.getCount() > 0)) {if (cursor.moveToFirst()) {int columnIndex = cursor.getColumnIndex(GesturePassword.REMAINOPPORTUNITY);return cursor.getString(columnIndex);}}} catch (Exception e) {} finally {if (cursor != null) {cursor.close();cursor = null;}}return "";}/*** 查询手势密码表--查看密码* */public String queryGesturePassword(SQLiteDatabase database) {Cursor cursor = null;try {cursor = database.query(publicSQLiteOpenHelper.GESTURE_PASSWORD, null, null, null, null, null, null);if ((cursor != null) && (cursor.getCount() > 0)) {if (cursor.moveToFirst()) {int columnIndex = cursor.getColumnIndex(GesturePassword.PASSWORD);return cursor.getString(columnIndex);}}} catch (Exception e) {} finally {if (cursor != null) {cursor.close();cursor = null;}}return "";}
}

接下里再看工具类把--就是输入的手势密码简单MD5加密、以及屏幕尺寸工具类

/*** */
package com.example.gesturelock;import android.content.Context;
import android.view.WindowManager;public class AppUtil {/*** 获取屏幕分辨�?* @param context* @return*/public static int[] getScreenDispaly(Context context) {WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);@SuppressWarnings("deprecation")int width = windowManager.getDefaultDisplay().getWidth();@SuppressWarnings("deprecation")int height = windowManager.getDefaultDisplay().getHeight();int result[] = { width, height };return result;}}


package com.example.gesturelock;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;import android.util.Log;public class MD5EncodeUtil {public static String MD5Ecode(String gesture){Log.i("GYL","gesture---"+gesture.toString());byte[] toencode=gesture.toString().getBytes();Log.i("GYL","byte[]----"+toencode.toString());try{MessageDigest md5=MessageDigest.getInstance("MD5");		md5.reset();md5.update(toencode);return HexEncode(md5.digest());}catch(NoSuchAlgorithmException e){e.printStackTrace();}return "";}public static String HexEncode(byte[] toencode){StringBuilder sb=new StringBuilder(toencode.length*2);for(byte b:toencode){sb.append(Integer.toHexString((b&0xf0)>>>4));sb.append(Integer.toHexString(b&0x0f));			}return sb.toString().toUpperCase();}
}

一步步来,接下来看bean类,就是每个圆点的属性

Constants

package com.example.gesturelock;public class Constants {public static final int POINT_STATE_NORMAL = 0; // 正常状态public static final int POINT_STATE_SELECTED = 1; // 按下状态public static final int POINT_STATE_WRONG = 2; // 错误状态}

GesturePoint

package com.example.gesturelock;import android.widget.ImageView;public class GesturePoint {/*** 左边x的值*/private int leftX;/*** 右边x的值*/private int rightX;/*** 上边y的值*/private int topY;/*** 下边y的值*/private int bottomY;/*** 这个点对应的ImageView控件*/private ImageView image;/*** 中心x值*/private int centerX;/*** 中心y值*/private int centerY;/*** 状态值*/private int pointState;/*** 代表这个Point对象代表的数字,从1开始(直接感觉从1开始)*/private int num;public GesturePoint(int leftX, int rightX, int topY, int bottomY,ImageView image, int num) {super();this.leftX = leftX;this.rightX = rightX;this.topY = topY;this.bottomY = bottomY;this.image = image;this.centerX = (leftX + rightX) / 2;this.centerY = (topY + bottomY) / 2;this.num = num;}public int getLeftX() {return leftX;}public void setLeftX(int leftX) {this.leftX = leftX;}public int getRightX() {return rightX;}public void setRightX(int rightX) {this.rightX = rightX;}public int getTopY() {return topY;}public void setTopY(int topY) {this.topY = topY;}public int getBottomY() {return bottomY;}public void setBottomY(int bottomY) {this.bottomY = bottomY;}public ImageView getImage() {return image;}public void setImage(ImageView image) {this.image = image;}public int getCenterX() {return centerX;}public void setCenterX(int centerX) {this.centerX = centerX;}public int getCenterY() {return centerY;}public void setCenterY(int centerY) {this.centerY = centerY;}public int getPointState() {return pointState;}public void setPointState(int state, int x, int y) {pointState = state;switch (state) {case Constants.POINT_STATE_NORMAL:this.image.setBackgroundResource(R.drawable.gesturewhite);break;case Constants.POINT_STATE_SELECTED:// 以原点为圆心,右下为正,左上为负if (y == 0 && x > 0) {this.image.setBackgroundResource(R.drawable.blueright);} else if (y == 0 && x < 0) {this.image.setBackgroundResource(R.drawable.blueleft);} else if (x == 0 && y > 0) {this.image.setBackgroundResource(R.drawable.bluedown);} else if (x == 0 && y < 0) {this.image.setBackgroundResource(R.drawable.blueup);} else if (x > 0 && y > 0) {this.image.setBackgroundResource(R.drawable.bluerightdown);} else if (x < 0 && y < 0) {this.image.setBackgroundResource(R.drawable.blueleftup);} else if (x < 0 && y > 0) {this.image.setBackgroundResource(R.drawable.blueleftdown);} else if (x > 0 && y < 0) {this.image.setBackgroundResource(R.drawable.bluerightup);} else if (x == 0 && y == 0) {this.image.setBackgroundResource(R.drawable.bluedot);}break;case Constants.POINT_STATE_WRONG:if (y == 0 && x > 0) {this.image.setBackgroundResource(R.drawable.redright);} else if (y == 0 && x < 0) {this.image.setBackgroundResource(R.drawable.redleft);} else if (x == 0 && y > 0) {this.image.setBackgroundResource(R.drawable.reddown);} else if (x == 0 && y < 0) {this.image.setBackgroundResource(R.drawable.redup);} else if (x > 0 && y > 0) {this.image.setBackgroundResource(R.drawable.redrightdown);} else if (x < 0 && y < 0) {this.image.setBackgroundResource(R.drawable.redleftup);} else if (x < 0 && y > 0) {this.image.setBackgroundResource(R.drawable.redleftdown);} else if (x > 0 && y < 0) {this.image.setBackgroundResource(R.drawable.redrightup);} else if (x == 0 && y == 0) {this.image.setBackgroundResource(R.drawable.reddot);}break;default:break;}}public int getNum() {return num;}public void setNum(int num) {this.num = num;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + bottomY;result = prime * result + ((image == null) ? 0 : image.hashCode());result = prime * result + leftX;result = prime * result + rightX;result = prime * result + topY;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;GesturePoint other = (GesturePoint) obj;if (bottomY != other.bottomY)return false;if (image == null) {if (other.image != null)return false;} else if (!image.equals(other.image))return false;if (leftX != other.leftX)return false;if (rightX != other.rightX)return false;if (topY != other.topY)return false;return true;}@Overridepublic String toString() {return "Point [leftX=" + leftX + ", rightX=" + rightX + ", topY="+ topY + ", bottomY=" + bottomY + "]";}
}

接下来就看那9个点的绘制界面

GestureContentView

package com.example.gesturelock;import java.util.ArrayList;
import java.util.List;import com.example.gesturelock.GestureDrawline.GestureCallBack;import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;/*** 手势密码容器类**/
public class GestureContentView extends ViewGroup {/*** 每个点区域的宽度*/private int blockWidth;private int spacing ;/*** 声明一个集合用来封装坐标集合*/private List<GesturePoint> list;private Context context;private GestureDrawline gestureDrawline;/*** 包含9个ImageView的容器,初始化* @param context* @param isVerify 是否为校验手势密码* @param passWord 用户传入密码* @param callBack 手势绘制完毕的回调*/public GestureContentView(Context context, boolean isVerify,String passWord, GestureCallBack callBack) {super(context);this.blockWidth = dip2px(context,66f); //圆圈的直径dp值this.spacing = dip2px(context, 30f); //圆圈之间的距离dp值this.list = new ArrayList<GesturePoint>();this.context = context;// 添加9个图标addChild();// 初始化一个可以画线的viewgestureDrawline = new GestureDrawline(context, list, isVerify,passWord, callBack);}public static int dip2px(Context context, float dpValue) {// TODO Auto-generated method stubfinal float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}private void addChild(){for (int i = 0; i < 9; i++) {ImageView image = new ImageView(context);image.setBackgroundResource(R.drawable.gesturewhite);			this.addView(image,new LayoutParams(blockWidth, blockWidth));invalidate();// 第几行int row = i / 3;// 第几列int col = i % 3;// 定义点的每个属性int leftX = col * blockWidth + col * spacing;int topY = row * blockWidth + row * spacing;int rightX = leftX + blockWidth;int bottomY = topY + blockWidth;//圆圈之间线的位置GesturePoint p = new GesturePoint(leftX, rightX, topY, bottomY, image,i+1);this.list.add(p);}}public void setParentView(ViewGroup parent){// 得到屏幕的宽度LayoutParams layoutParams = new LayoutParams(blockWidth * 3 + spacing * 2, blockWidth * 3 + spacing * 2);parent.addView(gestureDrawline,layoutParams);parent.addView(this,layoutParams);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {for (int i = 0; i < getChildCount(); i++) {//第几行int row = i/3;//第几列int col = i%3;View v = getChildAt(i);//用于绘制圆圈的位置,d表示X轴方向的偏移量,如果要上下移动整块手绘区域,则将top和bottom参数增加或减小一个合适的偏移量int leftX = col * blockWidth + col * spacing;int topY = row * blockWidth + row * spacing;int rightX = leftX + blockWidth;int bottomY = topY + blockWidth;v.layout(leftX, topY, rightX, bottomY)  ;}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}/*** 保留路径delayTime时间长* @param delayTime*/public void clearDrawlineState(long delayTime) {gestureDrawline.clearDrawlineState(delayTime);}}

然后继续看当手指连接时候,的那个绘制中间连线的代码

GestureDrawline

package com.example.gesturelock;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import android.annotation.SuppressLint;
import android.content.Context;import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff;
import android.os.Handler;import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;/*** 手势密码路径绘制* */
public class GestureDrawline extends View {private int mov_x;// 声明起点坐标private int mov_y;private Paint paint;// 声明画笔private Canvas canvas;// 画布private Bitmap bitmap;// 位图private List<GesturePoint> list;// private List<Pair<GesturePoint, GesturePoint>> lineList;// 记录画过的线private Map<String, GesturePoint> autoCheckPointMap;// 自动选中的情况点private boolean isDrawEnable = true; // 是否允许绘制/*** 屏幕的宽度和高度*/private int[] screenDispaly;private GesturePoint currentPoint;private GestureCallBack callBack;private StringBuilder passWordSb;private boolean isVerify;private String passWord;public GestureDrawline(Context context, List<GesturePoint> list,boolean isVerify, String passWord, GestureCallBack callBack) {super(context);//屏幕参数screenDispaly = AppUtil.getScreenDispaly(context);//画笔paint = new Paint(Paint.DITHER_FLAG);////初始化画布--宽高bitmap = Bitmap.createBitmap(screenDispaly[0], screenDispaly[0],Bitmap.Config.ARGB_8888); // canvas = new Canvas();canvas.setBitmap(bitmap);//设置画笔参数paint.setStyle(Style.STROKE);paint.setStrokeWidth(15);// paint.setColor(getResources().getColor(R.color.gestureline_green));// 设置默认连线颜色paint.setAntiAlias(true);//9个点的集合this.list = list;//画过的线集合this.lineList = new ArrayList<Pair<GesturePoint, GesturePoint>>();initAutoCheckPointMap();this.callBack = callBack;this.isVerify = isVerify;this.passWord = passWord;//密码集this.passWordSb = new StringBuilder();}private void initAutoCheckPointMap() {autoCheckPointMap = new HashMap<String, GesturePoint>();autoCheckPointMap.put("1,3", getGesturePointByNum(2));autoCheckPointMap.put("1,7", getGesturePointByNum(4));autoCheckPointMap.put("1,9", getGesturePointByNum(5));autoCheckPointMap.put("2,8", getGesturePointByNum(5));autoCheckPointMap.put("3,7", getGesturePointByNum(5));autoCheckPointMap.put("3,9", getGesturePointByNum(6));autoCheckPointMap.put("4,6", getGesturePointByNum(5));autoCheckPointMap.put("7,9", getGesturePointByNum(8));}/**得到对应的点位*/private GesturePoint getGesturePointByNum(int num) {for (GesturePoint point : list) {if (point.getNum() == num) {return point;}}return null;}/**将位图绘制到画布上*/@Overrideprotected void onDraw(Canvas canvas) {canvas.drawBitmap(bitmap, 0, 0, null);}// 触摸事件@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {if (isDrawEnable == false) {return true;}// 设置默认连线颜色paint.setColor(getResources().getColor(R.color.gestureline_green));switch (event.getAction()) {case MotionEvent.ACTION_DOWN:mov_x = (int) event.getX();mov_y = (int) event.getY();/**获取按下的点位*/currentPoint = getPointAt(mov_x, mov_y);if (currentPoint != null) {/**设置按下的点位的状态,保存密码*/currentPoint.setPointState(Constants.POINT_STATE_SELECTED, 0, 0);passWordSb.append(currentPoint.getNum());}invalidate();//回调方法callBack.onPointDown()  ;break;case MotionEvent.ACTION_MOVE://清楚痕迹clearScreenAndDrawList();//移动回调callBack.onGestureLineMove();//获取移动到的位置的点位GesturePoint pointAt = getPointAt((int) event.getX(),(int) event.getY());if (currentPoint == null && pointAt == null) {return true;} else {//由间隔处滑到原点处if (currentPoint == null && pointAt != null) {// 如果为空,那么把手指移动到的点赋值给currentPointcurrentPoint = pointAt;/**设置按下的点位的状态,保存密码*/currentPoint.setPointState(Constants.POINT_STATE_SELECTED,0, 0);passWordSb.append(currentPoint.getNum());}}/***/if (pointAt == null|| currentPoint.equals(pointAt)|| Constants.POINT_STATE_SELECTED == pointAt.getPointState()) {canvas.drawLine(currentPoint.getCenterX(),currentPoint.getCenterY(), event.getX(), event.getY(),paint);} else {int x = pointAt.getCenterX() - currentPoint.getCenterX();int y = pointAt.getCenterY() - currentPoint.getCenterY();currentPoint.setPointState(Constants.POINT_STATE_SELECTED, x, y);if (pointAt.equals(list.get(list.size() - 1))) {pointAt.setPointState(Constants.POINT_STATE_SELECTED, 0, 0);}GesturePoint betweenPoint = getBetweenCheckPoint(currentPoint,pointAt);if (betweenPoint != null&& Constants.POINT_STATE_SELECTED != betweenPoint.getPointState()) {// 存在中间点并且没有被选中Pair<GesturePoint, GesturePoint> pair1 = new Pair<GesturePoint, GesturePoint>(currentPoint, betweenPoint);lineList.add(pair1);passWordSb.append(betweenPoint.getNum());Pair<GesturePoint, GesturePoint> pair2 = new Pair<GesturePoint, GesturePoint>(betweenPoint, pointAt);lineList.add(pair2);passWordSb.append(pointAt.getNum());betweenPoint.setPointState(Constants.POINT_STATE_SELECTED,0, 0);currentPoint = pointAt;} else {Pair<GesturePoint, GesturePoint> pair = new Pair<GesturePoint, GesturePoint>(currentPoint, pointAt);lineList.add(pair);passWordSb.append(pointAt.getNum());currentPoint = pointAt;}}invalidate();break;case MotionEvent.ACTION_UP:isDrawEnable = false;if (isVerify) {// 手势密码校验String encodeString=MD5EncodeUtil.MD5Ecode(String.valueOf( passWordSb));String passwordMd5Ecode = MD5EncodeUtil.MD5Ecode(passWord);if (passwordMd5Ecode.equals(encodeString)) {callBack.checkedSuccess();} else {Log.e("TAG", "encode String fali");callBack.checkedFail();}} else {//重新绘制界面clearScreenAndDrawList();GesturePoint pointAtUp = getPointAt((int) event.getX(),(int) event.getY());if (pointAtUp != null&& currentPoint.equals(pointAtUp)&& Constants.POINT_STATE_SELECTED == pointAtUp.getPointState()&&passWordSb.length()==1) {currentPoint.setPointState(Constants.POINT_STATE_WRONG,0, 0);}invalidate();callBack.onGestureCodeInput(passWordSb.toString());}break;default:break;}return true;}/*** * @param delayTime*            延迟执行时间*/public void clearDrawlineState(long delayTime) {if (delayTime > 0) {// 绘制红色提示路线isDrawEnable = false;drawErrorPathTip();}new Handler().postDelayed(new clearStateRunnable(), delayTime);}/***/final class clearStateRunnable implements Runnable {public void run() {// 重置passWordSbpassWordSb = new StringBuilder();// 清空保存点的集合lineList.clear();// 重新绘制界面clearScreenAndDrawList();for (GesturePoint p : list) {p.setPointState(Constants.POINT_STATE_NORMAL, 0, 0);}invalidate();isDrawEnable = true;}}/*** * @param x* @param y*/private GesturePoint getPointAt(int x, int y) {for (GesturePoint point : list) {// 先判断xint leftX = point.getLeftX();int rightX = point.getRightX();if (!(x >= leftX && x < rightX)) {continue;}int topY = point.getTopY();int bottomY = point.getBottomY();if (!(y >= topY && y < bottomY)) {continue;}// 如果执行到这,那么说明当前点击的点的位置在遍历到点的位置这个地方return point;}return null;}private GesturePoint getBetweenCheckPoint(GesturePoint pointStart,GesturePoint pointEnd) {int startNum = pointStart.getNum();int endNum = pointEnd.getNum();String key = null;if (startNum < endNum) {key = startNum + "," + endNum;} else {key = endNum + "," + startNum;}return autoCheckPointMap.get(key);}/*** 清掉屏幕上所有的线,然后画出集合里面的线*/private void clearScreenAndDrawList() {canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);for (int i = 0; i < lineList.size(); i++){int r = 0,x,y;if ((lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2 < 0)r = -(lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2;else {r = (lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2;}float d = (float) 0.707 * r;x = lineList.get(i).second.getCenterX() -lineList.get(i).first.getCenterX();y = lineList.get(i).second.getCenterY() -lineList.get(i).first.getCenterY();if (i == lineList.size() - 1) {lineList.get(i).second.setPointState(Constants.POINT_STATE_SELECTED, 0, 0);lineList.get(i).first.setPointState(Constants.POINT_STATE_SELECTED, x, y);}else {lineList.get(i).first.setPointState(Constants.POINT_STATE_SELECTED, x, y);lineList.get(i).second.setPointState(Constants.POINT_STATE_SELECTED, x, y);}if (y == 0 && x > 0) {canvas.drawLine(lineList.get(i).first.getCenterX() + r,lineList.get(i).first.getCenterY(), lineList.get(i).second.getCenterX() - r,lineList.get(i).second.getCenterY(), paint);// 画线}else if (y == 0 && x < 0 ) {canvas.drawLine(lineList.get(i).first.getCenterX() - r,lineList.get(i).first.getCenterY(), lineList.get(i).second.getCenterX() + r,lineList.get(i).second.getCenterY(), paint);// 画线}else if (x == 0 && y > 0){canvas.drawLine(lineList.get(i).first.getCenterX(),lineList.get(i).first.getCenterY() + r, lineList.get(i).second.getCenterX(),lineList.get(i).second.getCenterY() - r, paint);// 画线}else if (x == 0 && y < 0 ) {				canvas.drawLine(lineList.get(i).first.getCenterX(),lineList.get(i).first.getCenterY() - r, lineList.get(i).second.getCenterX() ,lineList.get(i).second.getCenterY() + r, paint);// 画线}else if( x > 0 && y > 0 ){canvas.drawLine(lineList.get(i).first.getCenterX() + d,lineList.get(i).first.getCenterY() + d, lineList.get(i).second.getCenterX() - d ,lineList.get(i).second.getCenterY() - d, paint);// 画线}else if(x > 0 && y < 0 ){canvas.drawLine(lineList.get(i).first.getCenterX() + d,lineList.get(i).first.getCenterY() - d, lineList.get(i).second.getCenterX()-d ,lineList.get(i).second.getCenterY() + d, paint);// 画线				}else if (x < 0 && y > 0){canvas.drawLine(lineList.get(i).first.getCenterX() - d,lineList.get(i).first.getCenterY() + d, lineList.get(i).second.getCenterX()+d ,lineList.get(i).second.getCenterY() - d, paint);// 画线	}else if(x < 0 && y < 0 ){canvas.drawLine(lineList.get(i).first.getCenterX() - d,lineList.get(i).first.getCenterY() - d, lineList.get(i).second.getCenterX()+d ,lineList.get(i).second.getCenterY() + d, paint);// 画线	}}}private void drawErrorPathTip() {canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);paint.setColor(getResources().getColor(R.color.gestureline_red));// 设置默认线路颜色if(lineList.size() == 0  && currentPoint!= null){currentPoint.setPointState(Constants.POINT_STATE_WRONG, 0, 0);}for (int i = 0; i < lineList.size(); i++) {			int r = 0,x,y;if ((lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2 < 0)r = -(lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2;else {r = (lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2;}float d = (float) 0.707 * r;x = lineList.get(i).second.getCenterX() -lineList.get(i).first.getCenterX();y = lineList.get(i).second.getCenterY() -lineList.get(i).first.getCenterY();if (i == lineList.size() - 1) {lineList.get(i).second.setPointState(Constants.POINT_STATE_WRONG, 0, 0);lineList.get(i).first.setPointState(Constants.POINT_STATE_WRONG, x, y);}else {lineList.get(i).first.setPointState(Constants.POINT_STATE_WRONG, x, y);lineList.get(i).second.setPointState(Constants.POINT_STATE_WRONG, x, y);}if (y == 0 && x > 0) {canvas.drawLine(lineList.get(i).first.getCenterX() + r,lineList.get(i).first.getCenterY(), lineList.get(i).second.getCenterX() - r,lineList.get(i).second.getCenterY(), paint);// 画线}else if (y == 0 && x < 0 ) {canvas.drawLine(lineList.get(i).first.getCenterX() - r,lineList.get(i).first.getCenterY(), lineList.get(i).second.getCenterX() + r,lineList.get(i).second.getCenterY(), paint);// 画线}else if (x == 0 && y > 0){canvas.drawLine(lineList.get(i).first.getCenterX(),lineList.get(i).first.getCenterY() + r, lineList.get(i).second.getCenterX(),lineList.get(i).second.getCenterY() - r, paint);// 画线}else if (x == 0 && y < 0 ) {				canvas.drawLine(lineList.get(i).first.getCenterX(),lineList.get(i).first.getCenterY() - r, lineList.get(i).second.getCenterX() ,lineList.get(i).second.getCenterY() + r, paint);// 画线}else if( x > 0 && y > 0 ){canvas.drawLine(lineList.get(i).first.getCenterX() + d,lineList.get(i).first.getCenterY() + d, lineList.get(i).second.getCenterX() - d ,lineList.get(i).second.getCenterY() - d, paint);// 画线}else if(x > 0 && y < 0 ){canvas.drawLine(lineList.get(i).first.getCenterX() + d,lineList.get(i).first.getCenterY() - d, lineList.get(i).second.getCenterX()-d ,lineList.get(i).second.getCenterY() + d, paint);// 画线				}else if (x < 0 && y > 0){canvas.drawLine(lineList.get(i).first.getCenterX() - d,lineList.get(i).first.getCenterY() + d, lineList.get(i).second.getCenterX()+d ,lineList.get(i).second.getCenterY() - d, paint);// 画线	}else if(x < 0 && y < 0 ){canvas.drawLine(lineList.get(i).first.getCenterX() - d,lineList.get(i).first.getCenterY() - d, lineList.get(i).second.getCenterX()+d ,lineList.get(i).second.getCenterY() + d, paint);// 画线	}}invalidate();}public interface GestureCallBack {public abstract void onGestureCodeInput(String inputCode);public abstract void checkedSuccess();public abstract void checkedFail();public abstract void onGestureLineMove();public abstract void onPointDown() ;}}



ok 注备工作进行完毕,接下来看设置手势密码界面

gesture_edit.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:background="#f2f2f2" ><LinearLayoutandroid:id="@+id/ll_head"android:layout_width="fill_parent"android:layout_height="48dp"android:background="@drawable/bg_head"android:gravity="center_vertical"android:orientation="horizontal" ><LinearLayoutandroid:id="@+id/ll_head_left"android:layout_width="wrap_content"android:layout_height="fill_parent"android:layout_marginTop="1dp"android:gravity="center_vertical"android:background="@drawable/selector_head_back"android:orientation="horizontal" ><ImageViewandroid:id="@+id/im_back"android:layout_width="7dp"android:layout_height="14dp"android:layout_marginLeft="5dp"android:background="@drawable/back" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:text="@string/set_gesture_code"android:textColor="#fff"android:textSize="17.33dp" /></LinearLayout><Viewandroid:layout_width="0dp"android:layout_height="fill_parent"android:layout_weight="1" /></LinearLayout><LinearLayoutandroid:id="@+id/gesture_tip_layout"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_marginTop="75.67dp"android:orientation="vertical" ><TextViewandroid:id="@+id/tv_edit_texttip"android:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:text="@string/set_gesture_pattern"android:textColor="@color/color_black"android:textSize="@dimen/textsize_s3" /></LinearLayout><RelativeLayoutandroid:id="@+id/fl_edit_gesture_container"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="48dp"android:gravity="center_horizontal" ></RelativeLayout></LinearLayout>


GestureEditActivity

package com.example.gesturelock;import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;import com.example.gesturelock.GestureDrawline.GestureCallBack;public class GestureEditActivity extends Activity implements OnClickListener {private LinearLayout im_back;private TextView tv_texttip;private RelativeLayout mGestureContainer;private GestureContentView mGestureContentView;// 第一次输入的密码private String mFirstPassword = null;// 是不是第一次输入private boolean mIsFirstInput = true;static final String TABLES_NAME_GESTURE = "gesture_password";public final static int GESTURE_TIME = 8;private publicSQLiteOpenHelper sqliteInstance;private SQLiteDatabase database;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.gesture_edit);// 错误提示tv_texttip = (TextView) findViewById(R.id.tv_edit_texttip);// 9点区域mGestureContainer = (RelativeLayout) findViewById(R.id.fl_edit_gesture_container);// 返回im_back = (LinearLayout) findViewById(R.id.ll_head_left);// 初始化继续不可点击im_back.setOnClickListener(this);mGestureContentView = new GestureContentView(this, false, "",new GestureCallBack() {@Overridepublic void onGestureCodeInput(String inputCode) {if (mIsFirstInput) { // 第一次输入手势密码if (!isInputPassValidate(inputCode)) {// 至少连接4个点tv_texttip.setText(getResources().getString(R.string.drawguesturewarning));// 2秒后清除界面mGestureContentView.clearDrawlineState(2000L);// 2秒后还原提示mHandler.postDelayed(connect4Dot, 2000);return;}else {mFirstPassword = inputCode;tv_texttip.setText(getResources().getString(R.string.drawguestureagain));mHandler.postDelayed(clearGreenLine, 1000);mIsFirstInput = false;}} else {if (inputCode.equals(mFirstPassword)) { // 第二次输入手势密码与第一次一致tv_texttip.setText(getResources().getString(R.string.your_gesture_code));sqliteInstance = new publicSQLiteOpenHelper(GestureEditActivity.this);database = sqliteInstance.getWritableDatabase();boolean count = sqliteInstance.queryGestureTableCount(database);if (count) {//如果有记录sqliteInstance.updateGestureInfo(database,mFirstPassword, "8");}else {//如果没有记录sqliteInstance.insertGestureInfo(database,mFirstPassword, "8");}mHandler.postDelayed(setGestureOkFinish, 1000);} else {if (!isInputPassValidate(inputCode)) {// 至少连接4个点tv_texttip.setText(getResources().getString(R.string.drawguesturewarning));// 2秒后清除界面mGestureContentView.clearDrawlineState(2000L);// 2秒后还原提示mHandler.postDelayed(connect4Dot, 2000);} else { // 第二次输入手势密码与第一次不一致tv_texttip.setText(getResources().getString(R.string.drawagain));// 左右移动动画
//									 Animation shakeAnimation =
//									 AnimationUtils.loadAnimation(GestureEditActivity.this,R.anim.shake);
//									 tv_texttip.startAnimation(shakeAnimation);// 保持绘制的线,1.5秒后清除mGestureContentView.clearDrawlineState(2000L);mHandler.postDelayed(changeText2again, 2000);}}}}@Overridepublic void checkedFail() {}@Overridepublic void onGestureLineMove() {tv_texttip.setText(getResources().getString(R.string.release_hande_when_finish));}@Overridepublic void onPointDown() {}@Overridepublic void checkedSuccess() {}});// 设置手势解锁显示到哪个布局里面mGestureContentView.setParentView(mGestureContainer);}@Overrideprotected void onResume() {super.onResume();}Handler mHandler = new Handler();Runnable clearGreenLine = new Runnable() {public void run() {mGestureContentView.clearDrawlineState(0L);}};Runnable connect4Dot = new Runnable() {public void run() {tv_texttip.setText(getResources().getString(R.string.set_gesture_pattern));}};Runnable setGestureOkFinish = new Runnable() {public void run() {finish();}};Runnable changeText2again = new Runnable() {public void run() {tv_texttip.setText(getResources().getString(R.string.drawguestureagain));}};private boolean isInputPassValidate(String inputPassword) {if (TextUtils.isEmpty(inputPassword) || inputPassword.length() < 4) {return false;}return true;}protected void onDestroy() {super.onDestroy();}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.ll_head_left:finish();break;}}
}

最后看校验界面

gesture_verify.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:orientation="vertical"android:layout_height="match_parent"android:background="@color/color_main" ><LinearLayoutandroid:id="@+id/ll_head"android:layout_width="fill_parent"android:layout_height="48dp"android:background="@drawable/bg_head"android:gravity="center_vertical"android:orientation="horizontal" ><LinearLayoutandroid:id="@+id/ll_head_left"android:layout_width="wrap_content"android:layout_height="fill_parent"android:layout_marginTop="1dp"android:gravity="center_vertical"android:background="@drawable/selector_head_back"android:orientation="horizontal" ><ImageViewandroid:id="@+id/im_back"android:layout_width="7dp"android:layout_height="14dp"android:layout_marginLeft="5dp"android:background="@drawable/back" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:text="@string/verify_gesture_code"android:textColor="#fff"android:textSize="17.33dp" /></LinearLayout><Viewandroid:layout_width="0dp"android:layout_height="fill_parent"android:layout_weight="1" /></LinearLayout><LinearLayoutandroid:id="@+id/gesture_tip_layout"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_marginTop="75.67dp"android:orientation="vertical" ><TextViewandroid:id="@+id/tv_edit_texttip"android:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:text="@string/set_gesture_pattern"android:textColor="@color/color_black"android:textSize="@dimen/textsize_s3" /></LinearLayout><RelativeLayoutandroid:id="@+id/fl_verify_gesture_container"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="48dp"android:gravity="center_horizontal" ></RelativeLayout></LinearLayout>

最后校验代码

package com.example.gesturelock;import java.util.Timer;
import java.util.TimerTask;import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;import com.example.gesturelock.GestureDrawline.GestureCallBack;public class GestureVerifyActivity extends Activity {private static String TAG = "GestureVerifyActivity";private TextView tv_texttip;private RelativeLayout mGestureContainer;private LinearLayout ib_back;private GestureContentView mGestureContentView;private Timer timer = new Timer() ;private TimerTask closeActivityTask = null;static final String TABLES_NAME_GESTURE = "gesture_password";private int remainopportunity ;private publicSQLiteOpenHelper sqliteInstance;private SQLiteDatabase database;private void resetCloseEvent(){clearCloseEvent() ;closeActivityTask = new TimerTask() {public void run() {Message message = new Message();message.what = 1;handler.sendMessage(message);}};timer.schedule(closeActivityTask, 30000); }private void clearCloseEvent(){if(closeActivityTask != null){closeActivityTask.cancel() ;closeActivityTask = null ;Log.i(TAG, "----------closeActivityTask----------"+closeActivityTask);}}public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.gesture_verify);resetCloseEvent(); tv_texttip = (TextView) findViewById(R.id.tv_edit_texttip);ib_back = (LinearLayout) findViewById(R.id.ll_head_left);mGestureContainer = (RelativeLayout) findViewById(R.id.fl_verify_gesture_container);sqliteInstance = new publicSQLiteOpenHelper(GestureVerifyActivity.this);database = sqliteInstance.getWritableDatabase();//从数据库中获取手势密码、剩余次数firstPassward = sqliteInstance.queryGesturePassword(database);remainopportunityStr = sqliteInstance.queryGestureTime(database);if (TextUtils.isEmpty(remainopportunityStr)) {remainopportunity = 8;//初始化8次sqliteInstance.updateGestureInfo(database,null, "8");} else {remainopportunity = Integer.parseInt(remainopportunityStr);}if(remainopportunity == 0){tv_texttip.setTextColor(getResources().getColor(R.color.gestureline_red));tv_texttip.setText(getResources().getString(R.string.no_chance));}ib_back.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {finish();}});mGestureContentView = new GestureContentView(this, true, firstPassward,new GestureCallBack() {@Overridepublic void onGestureCodeInput(String inputCode) {}@SuppressLint("ShowToast")@Overridepublic void checkedSuccess() {sqliteInstance.updateGestureInfo(database,null, "8");mGestureContentView.clearDrawlineState(0L);resetCloseEvent();finish();//发送广播sendBroadcast(new Intent("com.godinsec.seland.intent.CASIntent.INTENT_LOAD_SD"));}@Overridepublic void checkedFail() {mGestureContentView.clearDrawlineState(2000L);tv_texttip.setTextColor(getResources().getColor(R.color.gestureline_red));if(remainopportunity > 0){remainopportunity-- ;}sqliteInstance.updateGestureInfo(database,null, ""+remainopportunity);resetCloseEvent();changeText();}@Overridepublic void onGestureLineMove() {if(remainopportunity > 0){tv_texttip.setTextColor(getResources().getColor(R.color.textcolor_black_bb));tv_texttip.setText(getResources().getString(R.string.release_hande_when_finish));}}@Overridepublic void onPointDown() {clearCloseEvent() ;}});mGestureContentView.setParentView(mGestureContainer);}protected void changeText() {Log.e("TAGG", "changeText");if (remainopportunity == 7) {tv_texttip.setText(getResources().getString(R.string.wrong_answer_seven));} else if (remainopportunity == 6) {tv_texttip.setText(getResources().getString(R.string.wrong_answer_six));} else if (remainopportunity == 5) {tv_texttip.setText(getResources().getString(R.string.wrong_answer_five));} else if (remainopportunity == 4) {tv_texttip.setText(getResources().getString(R.string.wrong_answer_four));} else if (remainopportunity == 3) {tv_texttip.setText(getResources().getString(R.string.wrong_answer_three));} else if (remainopportunity == 2) {tv_texttip.setText(getResources().getString(R.string.wrong_answer_two));} else if (remainopportunity == 1) {tv_texttip.setText(getResources().getString(R.string.wrong_answer_one));} else {tv_texttip.setText(getResources().getString(R.string.wrong_answer_zero));handler.postDelayed(errorFinish, 2000);}}@Overrideprotected void onResume() {super.onResume();}Runnable errorFinish = new Runnable() {public void run() {finish();}};@SuppressLint("HandlerLeak")Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case 1:finish();break;}}};private String remainopportunityStr;private String firstPassward;protected void onDestroy() {super.onDestroy();}protected void onStop() {super.onStop();}
}



这篇关于手势密码(四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125322

相关文章

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密 可以将表情,动物,水果,表情,手势,猫语,兽语,狗语,爱语,符号,数字,字母,加密和解密 可以将文字、字母、数字、代码、标点符号等内容转换成新的文字形式,通过简单的文字以不同的排列顺序来表达不同的内容 源码截图: https://www.httple.net/152649.html

mysql导出导入数据和修改登录密码

导出表结构: mysqldump -uroot -ppassword -d dbname tablename>db.sql; 导出表数据: mysqldump -t dbname -uroot -ppassword > db.sql 导出表结构和数据(不加-d): mysqldump -uroot -ppassword dbname tablename > db.sql;

Ubuntu 环境下ssh的安装、使用以及免密码登录

以两台机器为例:     A12.12.10.11B12.12.10.13 安装: Ubuntu默认安装了ssh客户端,只需要在被登录的机器上安装ssh服务器即可: $ sudo apt-get install openssh-server     启动ssh服务器: $ sudo /etc/init.d/ssh start 查看是否启动成功: $ ps -ef |grep

ubuntu 20.04 一直卡在登录界面,即使密码正确也无法登录(失败记录)

ubuntu 20.04 一直卡在登录界面,即使密码正确也无法登录 这次是装实体机,一次失败的尝试。。。 名称型号CPUIntel Xeon E5-2673 V3GPURTX 3060 mobile 安装的时候不要选install third-party software for graphics and Wi-fi hardware and additional media

oracle密码维护

查看密码是否可以重复使用 SQL> select PROFILE,RESOURCE_NAME,LIMIT from dba_profiles where profile='DEFAULT' and resource_type ='PASSWORD'; PROFILE                        RESOURCE_NAME                    LIMIT ----

【网络安全】古典密码体制概述

1. 古典密码体制概述 1.1 定义与历史背景 古典密码体制是指在计算机科学和信息安全技术出现之前的传统加密方法。这些方法主要包括替换和易位两种基本形式。古典密码体制的特点是简单、易用,但安全性不高,容易被破解。在古代,人们使用纸、笔或简单的器械来实现加密和解密操作。 定义:古典密码体制是基于简单数学运算和文字替换的加密方法,包括替代密码和置换密码两大类。历史背景:古典密码的使用可以追溯到古

vsftpd配置用户和密码让其他客户端连接

一、第一个主机:vsftpd下载及配置 前置准备: #卸载防火墙yum -y remove firewalld#为了不让防火墙有影响,iptables配置也清空iptables -Fvim /etc/selinux/confSELINUX=disabled #主要是把它改为disabled或者permissiveSELINUXTYPE=targeted#重启linux让selin

【linux mysql】mysql高版本8.0.23版本密码修改总结

mysql 8.0 版本,由于增加了一些安全策略等限制,所以修改用户密码会稍微麻烦些。下面是针对这个高版本的总结。 一、配置/etc/my.cnf 文件 免密码登录mysql vim /etc/my.cnf# 增加这两行命令skip-grant-tablesdefault-authentication-plugin=mysql_native_password 重启启动mysql se