zoukankan      html  css  js  c++  java
  • android指纹识别认证实现

    Android从6.0系统支持指纹认证功能

    启动页面简单实现

    package com.loaderman.samplecollect.zhiwen;
    
    import android.annotation.TargetApi;
    import android.app.FragmentManager;
    import android.app.KeyguardManager;
    import android.content.Intent;
    import android.hardware.fingerprint.FingerprintManager;
    import android.os.Build;
    import android.security.keystore.KeyGenParameterSpec;
    import android.security.keystore.KeyProperties;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.Toast;
    
    import com.loaderman.samplecollect.R;
    
    import java.security.KeyStore;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    
    public class GoActivity extends AppCompatActivity {
    
        private static final String DEFAULT_KEY_NAME = "default_key";
        KeyStore keyStore;
        private FragmentManager fragmentManager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_go);
            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;
                }
            }
            return true;
        }
    
        @TargetApi(23)
        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) { throw new RuntimeException(e); } } @TargetApi(23) 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); showFingerPrintDialog(cipher); } catch (Exception e) { throw new RuntimeException(e); } } private void showFingerPrintDialog(Cipher cipher) { FingerprintDialogFragment fragment = new FingerprintDialogFragment(); fragment.setCipher(cipher); fragmentManager = getFragmentManager(); fragment.show(fragmentManager,""); } public void onAuthenticated() { Intent intent = new Intent(this, MainActivity.class); startActivity(intent); finish(); } }

    指纹认证页面:

    package com.loaderman.samplecollect.zhiwen;
    
    import android.annotation.TargetApi;
    import android.app.DialogFragment;
    import android.content.Context;
    import android.hardware.fingerprint.FingerprintManager;
    import android.os.Bundle;
    import android.os.CancellationSignal;
    import android.support.annotation.Nullable;
    
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.loaderman.samplecollect.R;
    
    import javax.crypto.Cipher;
    
    @TargetApi(23)
    public class FingerprintDialogFragment extends DialogFragment {
        private FingerprintManager fingerprintManager;
        private CancellationSignal mCancellationSignal;
        private Cipher mCipher;
        private GoActivity mActivity;
        private TextView errorMsg;
        /**
         * 标识是否是用户主动取消的认证。
         */
        private boolean isSelfCancelled;
    
        public void setCipher(Cipher cipher) {
            mCipher = cipher;
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            mActivity = (GoActivity) getActivity();
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            fingerprintManager = getContext().getSystemService(FingerprintManager.class);
            setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);
        }
    
        @Nullable
        @Override
        public 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() {
                @Override
                public void onClick(View v) {
                    dismiss();
                    stopListening();
                }
            });
            return v;
        }
    
        @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();
            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);
        }
    
        private void stopListening() {
            if (mCancellationSignal != null) {
                mCancellationSignal.cancel();
                mCancellationSignal = null;
                isSelfCancelled = true;
            }
        }
    }

    认证布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <ImageView
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginTop="15dp"
            android:layout_gravity="center_horizontal"
            android:src="@drawable/ic_zhiwen" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:text="请验证指纹解锁"
            android:textColor="#000"
            android:textSize="16sp" />
    
        <TextView
            android: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:textColor="#f45"
            android:textSize="12sp" />
    
        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_marginTop="10dp"
            android:background="#ccc" />
    
        <TextView
            android:id="@+id/cancel"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center"
            android:text="取消"
            android:textColor="#5d7883"
            android:textSize="16sp" />
    </LinearLayout>

    认证成功后进入主页面

  • 相关阅读:
    一分钟认识:Cucumber框架(一)
    迭代=冲刺?
    Nresource服务之接口缓存化
    58集团支付网关设计
    服务治理在资源中心的实践
    资源中心——连接池调优
    4种常用的演讲结构: 黄金圈法则结构、PREP结构、时间轴结构、金字塔结构
    微服务时代,领域驱动设计在携程国际火车票的实践
    Sentinel -- FLOW SLOT核心原理篇
    管理篇-如何跨部门沟通?
  • 原文地址:https://www.cnblogs.com/loaderman/p/10180231.html
Copyright © 2011-2022 走看看