写点什么

Android 指纹识别 API 讲解,一种更快更好的用户体验,送给正在迷茫的你

用户头像
Android架构
关注
发布于: 2 小时前

<TextViewandroid:id="@+id/error_msg"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginTop="5dp"android:maxLines="1"android:textSize="12sp"android:textColor="#f45"/>


<Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:layout_marginTop="10dp"android:background="#ccc"/>


<TextViewandroid:id="@+id/cancel"android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"android:text="取消"android:textColor="#5d7883"android:textSize="16sp"/>


</LinearLayout>


这是一个非常简易的指纹认证界面,相信没什么需要解释的地方。界面大致样式如下图所示。



注意,通常为了让用户清楚的知道现在需要进行指纹认证,Google 官方建议最好使用一个通用的指纹图标,而不应该由各 APP 制作自己的指纹图标。为此,Google 也特意提供了一套指纹认证的组图,可以 [点击这里](


) 查看和下载。

接着我们创建一个 FingerprintDialogFragment 类,并让它继承自 DialogFragment,用于作为提示用户进行指纹认证的对话框,代码如下所示:


@TargetApi(23)public class FingerprintDialogFragment extends DialogFragment {


private FingerprintManager fingerprintManager;


private CancellationSignal mCancellationSignal;


private Cipher mCipher;


private LoginActivity mActivity;


private TextView errorMsg;


/**


  • 标识是否是用户主动取消的认证。*/private boolean isSelfCancelled;


public void setCipher(Cipher cipher) {mCipher = cipher;}


@Overridepublic void onAttach(Context context) {super.onAttach(context);mActivity = (LoginActivity) getActivity();}


@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);fingerprintManager = getContext().getSystemService(FingerprintManager.class);setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);}


@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {View v = inflater.inflate(R.layout.fingerprint_dialog, container, false);errorMsg = v.findViewById(R.id.error_msg);TextView cancel = v.findViewById(R.id.cancel);cancel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {dismiss();stopListening();}});return v;}


@Overridepublic void onResume() {super.onResume();


startListening(mCipher);}


@Overridepublic void onPause() {super.onPause();


stopListening();}


private void startListening(Cipher cipher) {isSelfCancelled = false;mCancellationSignal = new CancellationSignal();fingerprintManager.authenticate(new FingerprintManager.CryptoObject(cipher), mCancellationSignal, 0, new FingerprintManager.AuthenticationCallback() {@Overridepublic 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();}}}


@Overridepublic void onAuthenticationHelp(int helpCode, CharSequence helpString) {errorMsg.setText(helpString);}


@Overridepublic void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {Toast.makeText(mActivity, "指纹认证成功", Toast.LENGTH_SHORT).show();mActivity.onAuth


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


enticated();}


@Overridepublic void onAuthenticationFailed() {errorMsg.setText("指纹认证失败,请再试一次");}}, null);}


private void stopListening() {if (mCancellationSignal != null) {mCancellationSignal.cancel();mCancellationSignal = null;isSelfCancelled = true;}}


}


说了是实现一个最简版的指纹认证 Demo,因此这里的代码也都是非常简单的,基本上就是一个 Fragment 类的最普通实现,下面我带大家简单解析一下。


首先 setCipher() 方法用于接受一个 Cipher 对象,这个参数在待会进行指纹认证的时候会用到。

接下来几个生命周期方法都很简单,在 onAttach() 方法中获取了 Activity 的实例,在 onCreate() 方法获取了 FingerprintManager 的实例,在 onCreateView() 方法中加载了我们刚刚创建的 fingerprint_dialog.xml 布局,都是一些常规操作。


紧接着重点的要来了,在 onResume() 方法中调用了 startListening() 方法开始指纹认证监听,在 onPause() 方法中调用了 stopListening() 方法停止指纹认证监听。为什么要这么做呢?因为指纹传感器和摄像头类似,是不能多个程序同时使用的,因此任何一个程序都不应该在非前台时刻占用着指纹传感器的资源,所以需要在 onPause() 方法中及时释放资源。


那么,现在我们只需要把所有的目光都放在 startListening() 和 stopListening() 这两个方法上就可以了。在 startListening() 方法中,调用了 FingerprintManager 的 authenticate() 方法来开启指纹指纹监听。authenticate() 方法接收五个参数,第一个参数是 CryptoObject 对象,这里我们只需要将刚才传入的 Cipher 对象包装成 CryptoObject 对象就可以了。第二个参数是 CancellationSignal 对象,可以使用它来取消指纹认证操作。第三个参数是可选参数,官方的建议是直接传 0 就可以了。第四个参数用于接收指纹认证的回调,上述代码中我将所有的回调可能都进行了界面提示,方便大家观察。第五个参数用于指定处理回调的 Handler,这里直接传 null 表示回调到主线程即可。


而在 stopListening() 方法中的逻辑则简单得多了,我们只需要调用 CancellationSignal 的 cancel() 方法将指纹认证操作取消就可以了。


这样我们就将 FingerprintDialogFragment 中的代码全部完成了,这段代码可以直接复制到任意项目当中来作为指纹认证提醒对话框。

最后,我们再来编写一个简单的登录界面,整个指纹认证过程就完整了。创建 LoginActivity,代码如下所示:


public class LoginActivity extends AppCompatActivity {


private static final String DEFAULT_KEY_NAME = "default_key";


KeyStore keyStore;


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);if (supportFingerprint()) {initKey();initCipher();}}


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;}

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android指纹识别API讲解,一种更快更好的用户体验,送给正在迷茫的你