Android  指纹识别开发实例

Android M指纹的资料太少,经过一段时间阅读原生Android代码,写了以下例子,贡献出来给需要帮助的人。

  以下内容基于64位的高通CPU,搭载fpc1020芯片,此部分代码在原生android上做了更改,以应付工厂指纹的测试。原生android指纹录入需要采集10次(因不同的芯片而定)。

  代码简单说明:

  1. FingerPrintEnrollBase类:

  重要的是

Java代码

public interface Listener { 
  void onEnrollmentHelp(CharSequence helpString); 
  void onEnrollmentError(int errMsgId, CharSequence errString); 
  void onEnrollmentProgressChange(int steps, int remaining); 
} 

  这个接口。

  1)onEnrollmentHelp函数:是下层返回的指纹操作帮助信息。

  2)onEnrollmentError函数是下层返回的错误信息,errMsgId是错误信息类型,其中1表示指纹硬件不可用,3表示超时,5表示操作已取消。errString是errMsgId对应的文字信息,有需要的自己实验就知道了。

  3)onEnrollmentProgressChange()函数是显示当前指纹的采集情况,steps:总共需要录入多少次;remaining是剩余多少次,我在此函数中有打印Log。

  2. FingerPrintActivity是主Activity类,FingerPrintEnrollBase是指纹Base类。

  需要特别说明的是,在FingerPrintEnrollBase类中有一句:private byte[] mToken = new byte[69];这个数组正常情况是通过输入密码后经由framework层向hal层申请的,我这里为了省去验证那一块的代码,通过sizeof(hw_auth_token_t)计算出来的为69,需要的请依此计算。我在代码里实验过,此数组如果不是69(在64位CPU上),将直接导致程序crach!

       fpc指纹的采集流程图:

       源码如下:

       FingerPrintEnrollBase:

Java代码

/* 
 * Copyright (C) 2015 The Android Open Source Project 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License 
 */ 
 
package com.mediatek.test; 
 
import android.app.Activity; 
import android.app.Fragment; 
import android.content.Context; 
import android.hardware.fingerprint.FingerprintManager; 
import android.os.Bundle; 
import android.os.CancellationSignal; 
import android.os.Handler; 
import android.util.Log; 
/** 
 * local fragment to handle the state around fingerprint enrollment. 
 */ 
public class FingerPrintEnrollBase extends Fragment { 
 
 private int mEnrollmentSteps = -1; 
 private int mEnrollmentRemaining = 0; 
 private Listener mListener; 
 private boolean mEnrolling; 
 private CancellationSignal mEnrollmentCancel; 
 private Handler mHandler = new Handler(); 
 private byte[] mToken = new byte[69];//if byte length != sizeof(hw_auth_token_t), throws Exception 
 private boolean mDone; 
 private static final String TAG = "FingerPrintEnrollBase"; 
 
 @Override 
 public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setRetainInstance(true); 
 } 
 
 @Override 
 public void onAttach(Activity activity) { 
  super.onAttach(activity); 
 } 
 
 @Override 
 public void onStart() { 
  super.onStart(); 
  Log.d(TAG, "mToken length="+mToken.length); 
  if (!mEnrolling) { 
   FingerprintManager mFpM = (FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE); 
   startEnrollment(mFpM); 
  } 
 } 
 
 @Override 
 public void onStop() { 
  super.onStop(); 
  if (!getActivity().isChangingConfigurations()) { 
   cancelEnrollment(); 
  } 
 } 
 
 protected void startEnrollment(FingerprintManager mFpM) { 
  mHandler.removeCallbacks(mTimeoutRunnable); 
  mEnrollmentSteps = -1; 
  mEnrollmentCancel = new CancellationSignal(); 
  if(mFpM != null){ 
   mFpM.enroll(mToken, mEnrollmentCancel, 0, mEnrollmentCallback); 
  } 
  mEnrolling = true; 
 } 
 
 protected void cancelEnrollment() { 
  mHandler.removeCallbacks(mTimeoutRunnable); 
  if (mEnrolling) { 
   mEnrollmentCancel.cancel(); 
   mEnrolling = false; 
   mEnrollmentSteps = -1; 
  } 
 } 
 
 public void setListener(Listener listener) { 
  mListener = listener; 
 } 
 
 public int getEnrollmentSteps() { 
  return mEnrollmentSteps; 
 } 
 
 public int getEnrollmentRemaining() { 
  return mEnrollmentRemaining; 
 } 
 
 public boolean isDone() { 
  return mDone; 
 } 
 
 private FingerprintManager.EnrollmentCallback mEnrollmentCallback 
   = new FingerprintManager.EnrollmentCallback() { 
 
  @Override 
  public void onEnrollmentProgress(int remaining) { 
   if (mEnrollmentSteps == -1) { 
    mEnrollmentSteps = remaining; 
   } 
   mEnrollmentRemaining = remaining; 
   mDone = remaining == 0; 
   if (mListener != null) { 
    mListener.onEnrollmentProgressChange(mEnrollmentSteps, remaining); 
   } 
  } 
 
  @Override 
  public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { 
   if (mListener != null) { 
    mListener.onEnrollmentHelp(helpString); 
   } 
  } 
 
  @Override 
  public void onEnrollmentError(int errMsgId, CharSequence errString) { 
   if (mListener != null) { 
    mListener.onEnrollmentError(errMsgId, errString); 
   } 
  } 
 }; 
 
 private final Runnable mTimeoutRunnable = new Runnable() { 
  @Override 
  public void run() { 
   cancelEnrollment(); 
  } 
 }; 
 
 public interface Listener { 
  void onEnrollmentHelp(CharSequence helpString); 
  void onEnrollmentError(int errMsgId, CharSequence errString); 
  void onEnrollmentProgressChange(int steps, int remaining); 
 } 
} 

       FingerPrintActivity:

Java代码

package com.mediatek.test; 
 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.util.List; 
import java.util.Timer; 
import java.util.TimerTask; 
 
import android.R.color; 
import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.os.CancellationSignal; 
import android.os.Handler; 
import android.os.Message; 
import android.text.Spannable; 
import android.text.style.ForegroundColorSpan; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.ProgressBar; 
import android.widget.TableRow; 
import android.widget.TextView; 
import android.widget.Toast; 
 
import com.mediatek.test.R; 
import android.hardware.fingerprint.Fingerprint; 
import android.hardware.fingerprint.FingerprintManager; 
 
public class FingerPrintActivity extends Activity implements FingerPrintEnrollBase.Listener{ 
 private static final String TAG = "FingerPrintActivity"; 
 private MyHandler mHandler = new MyHandler(); 
 private TextView fingerPrintAcquisitionTextView, fingerPrintEnrollmentErrorView, fingerPrintEnrollmentHelpView; 
 private FingerPrintEnrollBase fpeb; 
 private FingerprintManager mFingerprintManager; 
  
 @Override 
 protected int setTitleId() { 
  return R.string.tittle_fingerprint; 
 } 
 
 @Override 
 protected Activity getActivity() { 
  return this; 
 } 
  
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.fingerprint); 
  fingerPrintAcquisitionTextView = (TextView)findViewById(R.id.fingerprint_message); 
  fingerPrintEnrollmentErrorView= (TextView)findViewById(R.id.fingerprint_enrollment_error); 
  fingerPrintEnrollmentHelpView= (TextView)findViewById(R.id.fingerprint_enrollment_help); 
 
  mFingerprintManager = (FingerprintManager) getActivity().getSystemService( 
    Context.FINGERPRINT_SERVICE); 
   
    
 } 
  
 private void sendMsgToHandler(int msgType, String remark){ 
  Message msg = Message.obtain(); 
  msg.what = msgType; 
  Bundle bundle = new Bundle(); 
  bundle.putString("result", remark); 
  msg.setData(bundle); 
  mHandler.sendMessage(msg); 
 } 
  
 @Override 
 public void onEnrollmentHelp(CharSequence helpString) { 
  Log.d(TAG, "==onEnrollmentHelp="+helpString.toString()); 
  sendMsgToHandler(3, helpString.toString()); 
 } 
 
 @Override 
 public void onEnrollmentError(int errMsgId, CharSequence errString) { 
  Log.d(TAG, "==onEnrollmentError errMsgId="+errMsgId+" errString="+errString.toString()); 
  if(errMsgId == 3){//time out 
   postEnrollment(); 
  }else if(errMsgId == 1){//hardware lose efficacy 
   startEnrollment(); 
  }else if(errMsgId == 5){//operation cancel 
  }else{ 
   sendMsgToHandler(4, errString.toString()); 
  } 
 } 
 
 @Override 
 public void onEnrollmentProgressChange(int steps, int remaining) { 
  Log.d(TAG, "===============onEnrollmentProgressChange======="); 
  Log.d(TAG, "steps" + steps + "||remaining=" + remaining); 
  fingerPrintEnrollmentHelpView.setText(""); 
  fingerPrintEnrollmentErrorView.setText(""); 
  sendMsgToHandler(2, getString(R.string.fingerprint_validate_success)); 
  buttonS.setEnabled(true); 
  stopFingerprint(); 
 } 
  
 private void startEnrollment(){ 
  if (fpeb == null) { 
   fpeb = new FingerPrintEnrollBase(); 
  } 
  fpeb.setListener(this); 
  fpeb.startEnrollment(mFingerprintManager); 
 } 
 private void postEnrollment(){ 
  if(mFingerprintManager != null){ 
   mFingerprintManager.postEnroll(); 
  } 
 } 
  
 private void stopFingerprint() { 
  if (fpeb != null){ 
   fpeb.cancelEnrollment(); 
   onStop(); 
  } 
 } 
  
 @Override 
 protected void onStart() { 
  super.onStart(); 
 } 
  
 @Override 
 protected void onStop() { 
  super.onStop(); 
  if(fpeb != null){ 
   fpeb.setListener(null); 
  } 
 } 
 
 @Override 
 protected void onResume() { 
  super.onResume(); 
  if(mFingerprintManager == null){ 
   mFingerprintManager = (FingerprintManager) getActivity().getSystemService( 
    Context.FINGERPRINT_SERVICE); 
  } 
   
  startEnrollment(); 
 } 
  
 @Override 
 protected void onPause() { 
  super.onPause(); 
  postEnrollment(); 
  mFingerprintManager = null; 
  stopFingerprint(); 
  fpeb = null; 
 } 
 
  
 class MyHandler extends Handler{ 
 
  @Override 
  public void handleMessage(Message msg) { 
   Bundle bundle = null; 
   super.handleMessage(msg); 
   switch (msg.what) { 
   case 0: 
    removeMessages(0); 
    bundle = msg.getData(); 
    String result = bundle.getString("result"); 
    selfTestView.setText(result); 
    selfTestView.setTextColor(result.contains("PASS")?Color.GREEN:Color.RED); 
    break; 
   case 1: 
    removeMessages(1); 
    bundle = msg.getData(); 
    String rs = bundle.getString("result"); 
    checkBroadView.setText(bundle.getString("result")); 
    checkBroadView.setTextColor(rs.contains("PASS")?Color.GREEN:Color.RED); 
    break; 
   case 2: 
    removeMessages(2); 
    bundle = msg.getData(); 
    String fingerprint = bundle.getString("result"); 
    fingerPrintAcquisitionTextView.setText(bundle.getString("result")); 
    fingerPrintAcquisitionTextView.setTextColor(fingerprint.contains("PASS")?Color.GREEN:Color.WHITE); 
    mButtonSelftest.setEnabled(true); 
    mButtonCheckerboardTest.setEnabled(true); 
    break; 
   case 3: 
    removeMessages(3); 
    bundle = msg.getData(); 
    String enrollmentHelp = bundle.getString("result"); 
    fingerPrintEnrollmentHelpView.setText(bundle.getString("result")); 
    break; 
   case 4: 
    removeMessages(4); 
    bundle = msg.getData(); 
    String enrollmentError = bundle.getString("result"); 
    fingerPrintEnrollmentErrorView.setText(bundle.getString("result")); 
    fingerPrintAcquisitionTextView.setText(""); 
    break; 
   default: 
    break; 
   } 
  } 
 } 
 
} 

以上就是对Android 指纹资料的整理,后续继续补充相关资料,谢谢大家对本站的支持!