Android 6.0+指纹识别心得
Android 6.0+Fingerprint心得
数据来源:https://blog.csdn.net/lhj1076880929/article/details/52297812
我的demo链接
google官方demo
google相关API:android.support.v4.hardware.fingerprint
具体实现:实现某个功能模块我认为最有效的方法就是找到该功能模块的启动方法(看别人代码我认为很有效的方法),然后逆推看明白整个工作流程。千万不要盲目的从第一行代码慢慢的一行一行的看,这样效率会很低,也很乏味。步入正题,先找到Fingerprint的启动方法:
/* Request authentication of a crypto object. This call warms up the fingerprint hardware and starts scanning for a fingerprint. It terminates when onAuthenticationError(int, CharSequence) or {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at which point the object is no longer valid. The operation can be canceled by using the provided cancel object. */ public void authenticate (FingerprintManagerCompat.CryptoObject crypto, int flags, CancellationSignal cancel, FingerprintManagerCompat.AuthenticationCallback callback, Handler handler)
这个方法是FingerprintManagerCompat类的公有方法,然后想办法把这个方法需要的几个参数给他,最后在调用他,这个功能大体就实现了;嗯,中间当然还有一些细节需要注意,比如如何实例化那几个类,可不可以传null之类的。下面给出我demo的具体代码,大家挑重要的看,然后按我说的方法看(这个方法authenticate着手哦),试试效果。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.contacts.lhj.myfingerprinttest"> <!--指纹权限--> <uses-permission android:name="android.permission.USE_FINGERPRINT" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".Main2Activity"/> </application> </manifest>
MainActivity
package com.contacts.lhj.myfingerprinttest; import android.annotation.TargetApi; import android.app.KeyguardManager; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.support.v4.hardware.fingerprint.FingerprintManagerCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.AppCompatButton; import android.view.View; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 0; private FingerPrintUiHelper fingerPrintUiHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { initFingerPrint(); AppCompatButton button = (AppCompatButton) findViewById(R.id.button); assert button != null; button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { jumpToGesturePassCheck(); } }); } else { jumpToMain2Activity(); } } private void jumpToMain2Activity() { Intent intent = new Intent(MainActivity.this, Main2Activity.class); startActivity(intent); finish(); } /** * 跳转到手势密码校验界面 */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void jumpToGesturePassCheck() { KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); Intent intent = keyguardManager.createConfirmDeviceCredentialIntent("finger", "测试指纹识别"); fingerPrintUiHelper.stopsFingerPrintListen(); startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS); } private void initFingerPrint() { fingerPrintUiHelper = new FingerPrintUiHelper(this); fingerPrintUiHelper.startFingerPrintListen(new FingerprintManagerCompat.AuthenticationCallback() { /** * Called when a fingerprint is recognized. * * @param result An object containing authentication-related data */ @Override public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) { Toast.makeText(MainActivity.this, "指纹识别成功", Toast.LENGTH_SHORT).show(); jumpToMain2Activity(); } /** * Called when a fingerprint is valid but not recognized. */ @Override public void onAuthenticationFailed() { Toast.makeText(MainActivity.this, "指纹识别失败", Toast.LENGTH_SHORT).show(); } /** * Called when a recoverable error has been encountered during authentication. The help * string is provided to give the user guidance for what went wrong, such as * "Sensor dirty, please clean it." * * @param helpMsgId An integer identifying the error message * @param helpString A human-readable string that can be shown in UI */ @Override public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { Toast.makeText(MainActivity.this, helpString, Toast.LENGTH_SHORT).show(); } /** * Called when an unrecoverable error has been encountered and the operation is complete. * No further callbacks will be made on this object. * * @param errMsgId An integer identifying the error message * @param errString A human-readable error string that can be shown in UI */ @Override public void onAuthenticationError(int errMsgId, CharSequence errString) { //但多次指纹密码验证错误后,进入此方法;并且,不能短时间内调用指纹验证 Toast.makeText(MainActivity.this, "errMsgId=" + errMsgId + "|" + errString, Toast.LENGTH_SHORT).show(); if (errMsgId == 7) { //出错次数过多(小米5测试是5次) jumpToGesturePassCheck(); } } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) { // Challenge completed, proceed with using cipher if (resultCode == RESULT_OK) { Toast.makeText(this, "识别成功", Toast.LENGTH_SHORT).show(); jumpToMain2Activity(); } else { Toast.makeText(this, "识别失败", Toast.LENGTH_SHORT).show(); } } } }
FingerPrintUiHelper
package com.contacts.lhj.myfingerprinttest; import android.app.Activity; import android.support.v4.hardware.fingerprint.FingerprintManagerCompat; import android.support.v4.os.CancellationSignal; /** * Small helper class to manage text/icon around fingerprint authentication UI. */ public class FingerPrintUiHelper { private CancellationSignal signal; private FingerprintManagerCompat fingerprintManager; public FingerPrintUiHelper(Activity activity) { signal = new CancellationSignal(); fingerprintManager = FingerprintManagerCompat.from(activity); } public void startFingerPrintListen(FingerprintManagerCompat.AuthenticationCallback callback) { fingerprintManager.authenticate(null, 0, signal, callback, null); } public void stopsFingerPrintListen() { signal.cancel(); signal = null; } }
Main2Activity
package com.contacts.lhj.myfingerprinttest; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class Main2Activity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); } }
gradle
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "24.0.0" defaultConfig { applicationId "com.contacts.lhj.myfingerprinttest" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' }
好了,布局就不贴了,很简单,自己随便弄几个控件就OK了,实在不行就下载demo吧。
主要类(这些类可以通过上面API链接查看):
类名 | 注释 | 我的翻译 |
---|---|---|
FingerprintManagerCompat | A class that coordinates access to the fingerprint hardware. | 一个用以访问指纹硬件的类 |
FingerprintManagerCompat.AuthenticationCallback | Callback structure provided to authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler) | 提供给方法authenticate的回调结构对象 |
FingerprintManagerCompat.AuthenticationResult | Container for callback data from authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler). | 一个用来存放来自方法authenticate的回调数据的容器。 |
FingerprintManagerCompat.CryptoObject | A wrapper class for the crypto objects supported by FingerprintManager. | FingerprintManager所支持的加密对象的包装类。 |
整个过程:这一次,当我决定了去做一个指纹识别的小功能的时候我第一件事是去google的开发者网站查看相关的API,这是由于我的潜意识就认为官方的才是权威、标准,这种想法其实也没问题;可是由于我的英语水平不咋的,所以只看了个半知半解,接着就做出了一个我不太满意有着bug的demo(主要是其中撤销指纹监听的功能一直做不出来)。我只能到百度、google这两个搜索引擎去寻找自己的答案了,终于我在google上面找到了答案(链接),这答案又指引我去看google官方的demo,最后终于把自己想做的demo完整的实现了。
总结:如果是需要短时间做出某个功能模块的话,尽量先使用自己比较擅长的能力去解决问题(这次我就该先百度或者google),因为重点是解决问题而不是完全弄清原理。时间充裕的话当然是去看API去看源码啰(小编尽量的在看了,只是看懂花的时间真的有点多啊!前辈说的话要听,慢慢来。。。呵呵)。