话说现在Android指纹解锁在不少的app中投入使用,代替了手动输入登录密码的繁琐,达到快速跳转到主界面的需求。话不多说上一张北京银行app的指纹登录截图:
查阅了文档后发现Android从6.0开始支持指纹验证了,首先你得手机的支持指纹这个功能,而Android手机厂商的手机硬件都是由各自生产的,并不能包保证就具有指纹的功能,那么我们还是要既做指纹登录还是要做密码输入登录,接下来做个demo验证指纹解锁的,首先我们先写一个Activity在判断是否支持指纹的逻辑:
public boolean supportFingerprint (){
if(Build.VERSION.SDK_INT <23){
Toast.makeText(this, "您的系统版本过低,不支持指纹功能", Toast.LENGTH_SHORT).show();
return false;
}else {
KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
if(!fingerprintManager.isHardwareDetected()){
Toast.makeText(this, "您的手机不支持指纹功能", Toast.LENGTH_SHORT).show();
return false;
}else if(!keyguardManager.isKeyguardSecure()){
Toast.makeText(this, "您还未设置锁屏,请先设置锁屏并添加一个指纹", Toast.LENGTH_SHORT).show();
return false;
}else if(!fingerprintManager.hasEnrolledFingerprints()){
Toast.makeText(this, "您至少需要在系统设置中添加一个指纹", Toast.LENGTH_SHORT).show();
return false;
}
}
return true;
}
如果硬件上支持了指纹,那么接下来我们就要处理获取加密以及生成Cipher对象的逻辑了。
第一步:生成一个对称加密的key
private void initKey(){
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(DEFAULT_KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
keyGenerator.init(builder.build());
keyGenerator.generateKey();
} catch (Exception e) {
e.printStackTrace();
}
}
第二步:生成一个Cipher对象
private void initCipher(){
try {
SecretKey key = (SecretKey) keyStore.getKey(DEFAULT_KEY_NAME, null);
Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
cipher.init(Cipher.ENCRYPT_MODE, key);
//弹出验证指纹的dialog
showFingerPrintDialog(cipher);
} catch (Exception e) {
e.printStackTrace();
}
}
第三步:当界面可见时处理指纹认证监听,界面不可见时停止指纹认证的监听
@Override
public void onResume() {
super.onResume();
// 开始指纹认证监听
startListening(mCipher);
}
@Override
public void onPause() {
super.onPause();
// 停止指纹认证监听
stopListening();
}
private void startListening(Cipher cipher) {
isSelfCancelled = false;
mCancellationSignal = new CancellationSignal();
/**
* authenticate()方法接收五个参数,
* 第一个参数是CryptoObject对象,传入Cipher对象就可以了。
* 第二个参数是CancellationSignal对象,可以使用它来取消指纹认证操作。
* 第三个参数是可选参数,官方的建议是直接传0就可以了。
* 第四个参数用于接收指纹认证的回调,上述代码中将所有的回调可能都进行了界面提示。
* 第五个参数用于指定处理回调的Handler,这里直接传null表示回调到主线程即可
*/
fingerprintManager.authenticate(new FingerprintManager.CryptoObject(cipher), mCancellationSignal, 0, new FingerprintManager.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
if (!isSelfCancelled) {
errorMsg.setText(errString);
if (errorCode == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT) {
Toast.makeText(mActivity, errString, Toast.LENGTH_SHORT).show();
dismiss();
}
}
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
errorMsg.setText(helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
Toast.makeText(mActivity, "指纹认证成功", Toast.LENGTH_SHORT).show();
mActivity.onAuthenticated();
}
@Override
public void onAuthenticationFailed() {
errorMsg.setText("指纹认证失败,请再试一次");
}
}, null);
}
/**
* 调用CancellationSignal的cancel()方法将指纹认证操作
*/
private void stopListening() {
if(mCancellationSignal != null){
mCancellationSignal.cancel();
mCancellationSignal = null;
isSelfCancelled = true;
}
}
此处重点讲一下开始认证监听的方法:
fingerprintManager.authenticate()接收五个参数,
* 第一个参数是CryptoObject对象,传入Cipher对象就可以了。
* 第二个参数是CancellationSignal对象,可以使用它来取消指纹认证操作。
* 第三个参数是可选参数,官方的建议是直接传0就可以了。
* 第四个参数用于接收指纹认证的回调,上述代码中将所有的回调可能都进行了界面提示。
* 第五个参数用于指定处理回调的Handler,这里直接传null表示回调到主线程即可
在第四个参数处有4个回调方法
第一个onAuthenticationError()处理了用户点击取消了指纹验证的逻辑
第二个onAuthenticationHelp()处理了授权帮助的提示
第三个onAuthenticationSucceede()处理了授权成功后跳转到主页面
第四个onAuthenticationFailed()处理了授权失败再试一次的提示
在清单文件中添加权限:<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
到此指纹解锁的逻辑就处理完了,希望对由此需求的同学们会有帮助,谢谢。下载完整代码请点击:
demo下载