九宫格手势密码
项目Github地址GesturePassword项目
九宫格密码的使用一般分为两种场景:
- 系统级别的锁屏密码
- App级别的登录、启动验证
本篇文章主要介绍的是App级别的启动验证,主要从三方面介绍:
1、提供已经写好的九宫格密码View。
2、讲解九宫格密码View的使用方法。
3、九宫格密码View的UI的自定义更改。
####废话不说,上图
一、本文中用的九宫格密码自定义View参看Github项目当中的文件
二、密码View的使用方法
(1)xml文件,像其他控件一样直接使用
<com.example.gesturepassword.GesturePassword
android:id="@+id/gesturePwdView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintDimensionRatio="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTitleGesture" />
(2)代码当中的处理
gesturePwdView.setOnCompleteListener(object : GesturePassword.OnCompleteListener{
override fun onComplete(password: String?) {
TODO("Not yet implemented")
//密码输入完成操作,password为明文密码例如"12369"
}
override fun onPasswordTooShort() {
TODO("Not yet implemented")
//密码太短触发的方法
}
})
在onComplete(String mPassword){}方法里可以进行是设置密码还是验证密码的判断操作,判断依据是存储到SharePreference里的MD5加密的手势密码是否为空。所以下边有两个结果:
1、设置密码(也有两个结果A/B)
**A:**用户是第一次绘制密码,暂存等待用户第二次绘制。 **B:**用户是第二次绘制,绘制完成和第一次绘制结果比较,不一致要求重新绘制,一致的话就MD5加密存储到SharePreference,并关闭当前设置页面。
2、验证密码(判断用户此次输入密码是否和存储的密码一致)
**A:**密码一致则关闭当前页面,正常显示其他页面。 **B:**密码不一致,提示用户重试,如果输错达到限制可以做清空登陆信息、清空密码、关闭App登操作。
九宫格手势密码View其他方法可以clone项目看源码
###三、九宫格UI样式的自定义更改
1、颜色:所给出的自定义View里边都有详细的注释说明,主要包括
- 内外圈颜色
- 连接线颜色
- 连接线上的箭头颜色
- 选中状态的颜色
- 错误状态的颜色
指纹密码
关于指纹是否可用和校验的方法都在FingerUtils工具类当中,如下
import android.app.KeyguardManager;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.CancellationSignal;
import android.os.Handler;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
/**
* 指纹识别工具类
*/
public class FingerUtils {
private final KeyguardManager keyguardManager;
private static FingerUtils singleton = null;
//指纹识别结果监听接口
private static OnFingerCheckListener mOnFingerCheckListener;
//AndroidP版本之下的生物识别
private final FingerprintManager fingerprintManager;
//生物识别取消类
private static CancellationSignal mCancelSignal;
@RequiresApi(api = Build.VERSION_CODES.M)
private FingerUtils(Context context) {
fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
}
@RequiresApi(api = Build.VERSION_CODES.M)
public static FingerUtils getInstance(Context context) {
if (singleton == null) {
synchronized (FingerUtils.class) {
if (singleton == null) {
singleton = new FingerUtils(context);
}
}
}
return singleton;
}
/**
* 检查手机硬件(有没有指纹感应区)
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public boolean isHardFinger() {
return fingerprintManager != null && fingerprintManager.isHardwareDetected();
}
/**
* 检查手机是否开启锁屏密码
*/
public boolean isWindowSafe() {
return keyguardManager != null && keyguardManager.isKeyguardSecure();
}
/**
* 检查手机是否已录入指纹
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public boolean isHaveHandler() {
return fingerprintManager != null && fingerprintManager.hasEnrolledFingerprints();
}
/**
* 创建指纹验证
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public void authenticate(FingerprintManager.CryptoObject cryptoObject,
CancellationSignal cancellationSignal,
int flag,
FingerprintManager.AuthenticationCallback authenticationCallback,
Handler handler) {
if (fingerprintManager != null) {
fingerprintManager.authenticate(cryptoObject, cancellationSignal, flag, authenticationCallback, handler);
}
}
//
@RequiresApi(api = Build.VERSION_CODES.M)
public void authFingerPrint() {
//重新创建指纹识别取消类,如果使用同一个无法取消后再次开启
mCancelSignal = new CancellationSignal();
FingerprintManager.AuthenticationCallback mFingerCallBack = new FingerprintManager.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
if (mOnFingerCheckListener != null)
mOnFingerCheckListener.onCheckFailed(errString.toString());
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
super.onAuthenticationHelp(helpCode, helpString);
if (mOnFingerCheckListener != null)
mOnFingerCheckListener.onCheckFailed(helpString.toString());
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
if (mOnFingerCheckListener != null) mOnFingerCheckListener.onCheckSuccess();
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
if (mOnFingerCheckListener != null)
mOnFingerCheckListener.onCheckFailed("识别失败,请重试!");
}
};
fingerprintManager.authenticate(null, mCancelSignal, 0, mFingerCallBack, null);
}
//开启指纹识别
@RequiresApi(api = Build.VERSION_CODES.M)
public void setFingerAuth(Context context, OnFingerCheckListener listener) {
if (isHardFinger()) {
if (isWindowSafe() && isHaveHandler()) {
setFingerCheckListener(listener);
authFingerPrint();
} else {
Toast.makeText(context, "请先录入指纹", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "手机硬件不支持指纹识别", Toast.LENGTH_SHORT).show();
}
}
//取消指纹识别认证
public void cancelFingerAuth() {
if (mCancelSignal != null) mCancelSignal.cancel();
}
public FingerUtils setFingerCheckListener(OnFingerCheckListener listener) {
mOnFingerCheckListener = listener;
return singleton;
}
//指纹检查结果监听接口回调
public interface OnFingerCheckListener {
void onCheckSuccess();
void onCheckFailed(String message);
}
}