安卓中图案解锁的实现原理和实现过程

这里写图片描述
由上图,可以看出,图案中手势的记录是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
    }

    @Override
    public 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();
    }

    @Override
    protected 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){
                    // normol
                    canvas.drawBitmap(bitmapPointNormal, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);
                }
                else if(points[i][j].state == Point.STATE_PRESS){
                    // press
                    canvas.drawBitmap(bitmapPointPress, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);
                }
                else{
                    // error
                    canvas.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;
    }


}
</integer></integer></integer></point></point></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);
    }
}
</integer></integer></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;
                }
            }
        });
    }
}
</integer>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 13 禁用图案解锁可以通过以下步骤实现: 1. 在 AndroidManifest.xml 文件添加权限声明: ```xml <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> ``` 2. 在你的 Activity 添加以下代码: ```java KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (keyguardManager.isKeyguardSecure()) { Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(null, null); if (intent != null) { startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS); } else { // 现在没有设置锁屏密码 } } else { // 没有启用任何安全锁屏 } ``` 3. 在 onActivityResult 方法添加以下代码: ```java if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) { if (resultCode == RESULT_OK) { // 成功验证设备凭据,可以禁用图案解锁了 DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName componentName = new ComponentName(this, DeviceAdminReceiver.class); if (devicePolicyManager.isAdminActive(componentName)) { devicePolicyManager.setPasswordQuality(componentName, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); devicePolicyManager.resetPassword("", DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY); devicePolicyManager.lockNow(); } } else { // 验证失败,不能禁用图案解锁 } } ``` 这样就可以禁用图案解锁了。需要注意的是,在不需要禁用图案解锁时,应该调用 `devicePolicyManager.setPasswordQuality(componentName, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)` 来重新启用图案解锁

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值