Android中图案解锁的设计原理和实现过程
来源:互联网 发布:seo编辑工具 编辑:程序博客网 时间:2024/04/29 09:17
Android中图案解锁
首先要理解图案的实现原理,上一张图:
由上图,可以看出,图案中手势的记录是1-9或0-8的,保存的顺序就是密码,当然有些是可以重复的,为了安全,肯定不能直接存原顺序,一定是要加密处理的,如MD5或Hash散列。
(作者: a day a better)
图案解锁中自定义View,是其中最为关键的一部分。下面是自定义LockView的实现,里面的注释写的很详细了。
<span style="font-size:14px;">package com.example.patternlock;import java.util.ArrayList;import java.util.List;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.util.AttributeSet;import android.view.MotionEvent;import android.view.View;public class LockView extends View {private boolean inited = false;Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);// 抗锯齿Paint pressPaint = new Paint(); //按下时的画笔Paint errorPaint = new Paint(); //错误时的画笔private Bitmap bitmapPointError;private Bitmap bitmapPointPress;private Bitmap bitmapPointNormal;private float bitmapR; // 点的半径private boolean isDraw = false; //是否正在绘制float mouseX, mouseY;private Point [][] points = new Point[3][3];private ArrayList<Point> pointList = new ArrayList<Point>(); //保存经过的点private ArrayList<Integer> passList = new ArrayList<Integer>();private OnDrawFinishedListener listener;public LockView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// TODO Auto-generated constructor stub}public LockView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public LockView(Context context) {super(context);// TODO Auto-generated constructor stub}@Overridepublic boolean onTouchEvent(MotionEvent event) {mouseX = event.getX();mouseY = event.getY();int [] ij;int i , j;switch (event.getAction()) {case MotionEvent.ACTION_DOWN:resetPoints();ij = getSelectedPoint();if(ij != null){isDraw = true;i = ij[0];j = ij[1];points[i][j].state = Point.STATE_PRESS;pointList.add(points[i][j]);passList.add(i * 3 + j);}break;case MotionEvent.ACTION_MOVE:if(isDraw){ij = getSelectedPoint();if(ij != null){i = ij[0];j = ij[1];if(!pointList.contains(points[i][j])){points[i][j].state = Point.STATE_PRESS;pointList.add(points[i][j]);passList.add(i * 3 + j);}}}break;case MotionEvent.ACTION_UP:boolean valid = false;if(listener != null && isDraw){valid = listener.OnDrawFinished(passList);}if(!valid){for (Point p:pointList) {p.state = Point.STATE_ERROR;}}isDraw = false;break;default:break;}this.postInvalidate();return true;}private int[] getSelectedPoint() {Point pMouse = new Point(mouseX,mouseY);for (int i = 0; i < points.length; i++) {for (int j = 0; j < points[i].length; j++) {if(points[i][j].distance(pMouse) < bitmapR){int [] result = new int [2];result[0] = i;result[1] = j;return result;}}}return null;}public void resetPoints() {passList.clear();pointList.clear();for (int i = 0; i < points.length; i++) { for (int j = 0; j < points[i].length; j++) { points[i][j].state = Point.STATE_NORMOL; } }this.postInvalidate();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if(!inited){init();}drawPoints(canvas);if(pointList.size() > 0){ //画线 2->3,3->5 ...Point a = pointList.get(0);for (int i = 1;i < pointList.size(); i++) { Point b = pointList.get(i); drawLine(canvas, a, b); a = b; }if(isDraw){ // 画最后一个点drawLine(canvas, a, new Point(mouseX, mouseY));}}}private void drawLine(Canvas canvas, Point a, Point b) {if(a.state == Point.STATE_ERROR){canvas.drawLine(a.x, a.y, b.x, b.y, errorPaint);}else if(a.state == Point.STATE_PRESS){canvas.drawLine(a.x, a.y, b.x, b.y, pressPaint);}}private void drawPoints(Canvas canvas) {for (int i = 0; i < points.length; i++) {for (int j = 0; j < points[i].length; j++) {if(points[i][j].state == Point.STATE_NORMOL){// normolcanvas.drawBitmap(bitmapPointNormal, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);}else if(points[i][j].state == Point.STATE_PRESS){// presscanvas.drawBitmap(bitmapPointPress, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);}else{// errorcanvas.drawBitmap(bitmapPointError, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);}}}}private void init() {pressPaint.setColor(Color.YELLOW);pressPaint.setStrokeWidth(4);errorPaint.setColor(Color.RED);errorPaint.setStrokeWidth(4);bitmapPointError = BitmapFactory.decodeResource(getResources(), R.drawable.error);bitmapPointNormal = BitmapFactory.decodeResource(getResources(), R.drawable.normal);bitmapPointPress = BitmapFactory.decodeResource(getResources(), R.drawable.press);bitmapR = bitmapPointError.getWidth() / 2; //三种点的大小一样int width = getWidth();int height = getHeight();int offset = Math.abs(width - height) / 2;int offsetX, offsetY;int space;if(width > height){space = height / 4;offsetX = offset;offsetY = 0;}else{space = width / 4;offsetX = 0;offsetY = offset;}points[0][0] = new Point(offsetX +space , offsetY + space);points[0][1] = new Point(offsetX + 2*space , offsetY + space);points[0][2] = new Point(offsetX + 3 * space , offsetY + space);points[1][0] = new Point(offsetX +space, offsetY + 2 * space);points[1][1] = new Point(offsetX + 2 * space , offsetY + 2 * space);points[1][2] = new Point(offsetX + 3 * space , offsetY + 2 * space);points[2][0] = new Point(offsetX +space, offsetY + 3 * space);points[2][1] = new Point(offsetX + 2 * space , offsetY + 3 * space);points[2][2] = new Point(offsetX + 3 * space , offsetY + 3 * space);inited = true; //初始化完成}public interface OnDrawFinishedListener{boolean OnDrawFinished(List<Integer> passList);}public void setOnDrawFinishedListener(OnDrawFinishedListener listener){this.listener = listener;}}</span>
设置密码:
<span style="font-size:14px;">package com.jikexueyuan.screenlock;import android.content.Intent;import android.content.SharedPreferences;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.Toast;import java.util.List;public class SettingActivity extends ActionBarActivity { List<Integer> passList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_setting); final GestureLock lock = (GestureLock)findViewById(R.id.LockView); Button btn_reset = (Button)findViewById(R.id.btn_reset); Button btn_save = (Button)findViewById(R.id.btn_save); lock.setOnDrawFinishedListener(new GestureLock.OnDrawFinishedListener() { @Override public boolean OnDrawFinished(List<Integer> passList) { if (passList.size() < 3) { Toast.makeText(SettingActivity.this, "密码不能少于3个点", Toast.LENGTH_SHORT).show(); return false; } else { SettingActivity.this.passList = passList; return true; } } }); btn_reset.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { lock.resetPoints(); } }); btn_save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (passList != null) { StringBuilder sb = new StringBuilder(); for (Integer i : passList) { sb.append(i); } SharedPreferences sp = SettingActivity.this.getSharedPreferences("password", SettingActivity.this.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString("password", sb.toString()); editor.commit(); Toast.makeText(SettingActivity.this, "保存完成", Toast.LENGTH_SHORT).show(); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_setting, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); }}</span>
检验密码:
package com.example.patternlock;import android.app.Activity;import android.content.SharedPreferences;import android.os.Bundle;import android.widget.Toast;import java.util.List;import com.example.patternlock.LockView.OnDrawFinishedListener;public class LockActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lock); SharedPreferences sp = getSharedPreferences("password", this.MODE_PRIVATE); final String password = sp.getString("password", ""); LockView lock = (LockView)findViewById(R.id.LockView); lock.setOnDrawFinishedListener(new OnDrawFinishedListener() { @Override public boolean OnDrawFinished(List<Integer> passList) { StringBuilder sb = new StringBuilder(); for (Integer i : passList) { sb.append(i); } if (sb.toString().equals(password)){ Toast.makeText(LockActivity.this, "正确", Toast.LENGTH_SHORT).show(); return true; } else { Toast.makeText(LockActivity.this, "错误", Toast.LENGTH_SHORT).show(); return false; } } }); }}
详细代码和注释在下面的链接中,欢迎大家学习。
http://download.csdn.net/detail/adayabetter/8923241
1 0
- Android中图案解锁的设计原理和实现过程
- 安卓中图案解锁的实现原理和实现过程
- android图案解锁功能的实现
- 基于Android的图案解锁实现
- [Android UI]android-lockpattern图案解锁的实现分享
- Android实现九宫格图案解锁
- Android 图案解锁
- Android中图案锁的实现
- Android中图案锁的实现
- [源码]Android安卓应用手势锁图案解锁的实现
- Android屏幕解锁图案破解
- Android屏幕解锁图案破解
- Android屏幕解锁图案破解
- Android屏幕解锁图案破解
- Android屏幕解锁图案破解
- Android屏幕解锁图案破解
- Android屏幕解锁图案破解
- Android屏幕解锁图案破解
- C#+Socket客户端断线重连的解决办法
- ReentrantLock(重入锁)以及公平性
- poj3126
- 研究Openshare的原理
- Nginx 作为web server 的优化要点
- Android中图案解锁的设计原理和实现过程
- ubuntu 安装 vsftpd
- 问题解决--实现仿微信多图选择的开源项目(MultiImageSelector)
- Opencv+VS2010配置
- WSTMall怎么--WSTMall致力O2O开源软件降低企业成本
- Mathematica 表达式求值
- Java 中replaceAll忽略大小写
- Jsoup学习笔记7之File类操作文件:复制只包含指定类型文件的文件夹,并在新创建的同名文件夹中创建同名的另一种格式的文件
- C语言中 float double在内存中的存储