Android 6.0 之后Google官方推出了指纹识别,但是很多厂商在6.0之前就有了指纹识别这一功能,这就涉及到了适配问题,不可能抛弃6.0之前的用户。
1,先介绍6.0之后的指纹识别的使用,虽然很简单,但也有几个坑。这里有两种方法获取到指纹对象。
FingerprintManager mManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
FingerprintManagerCompat mManager = FingerprintManagerCompat.from(this);
一开始我以为用哪个都可以,反正只是兼容6.0以上的,但在使用第一种的时候在6.0以下就会崩溃,使用try catch都没用,在我的印象里try catch应该是能否捕获所有的异常,但不知为什么就没有捕获到这个ClassNotFoundException,不知有没有知道为什么的,希望给个提示,虽然可以先判断版本,但我怕特殊机型会出问题,就使用了兼容包里的FingerprintManagerCompat,但万万没想到,不好使,监听没有回掉,判断返回都是false,这弄的我很是诧异,偶然间发现当兼容包v4 v7 包依赖为25.0.0时是好使的,所以没办法只能是回滚了,这里还有一个需要注意的东西,项目中类库的包的兼容包依赖版本不能高于项目中的。
2,兼容三星的指纹识别
http://developer.samsung.com/galaxy/pass# 可以在这个地址中下载三星指纹识别需要的sdk,通过使用他的demo,可以很容易的容,在后面代码中会介绍几个常用的方法。三星给了自己的指纹识别dialog,而google并没有给指纹识别的界面,开发时因为时间原因就没有找怎么更改他给的dialog。而其他的则是模仿ios的指纹提示页面。还有我原以为6.0之后用google的就会好使,但没想到有的三星手机升级6.0之后并不好使,没有直接6.0系统的三星手机,所以就只能判断以下版本在判断以下有三星的sdk是否好使了,不好使在用google的方法。
3,兼容魅族手机
http://open-wiki.flyme.cn/index.php?title=%E6%8C%87%E7%BA%B9%E8%AF%86%E5%88%ABAPI 可以在这个地址中下载魅族手机指纹识别需要的sdk,这个就比较简单了,6.0以下使用这个,6.0以上使用官方的,但不知为什么没有api介绍,难道是我没有找到?里面有两个方法让我很是纠结不知那个是判断是否支持指纹,也没有那么多的测试机。
FingerprintManager open = FingerprintManager.open();
open.isSurpport()
open.isFingerEnable()
4,代码:
/**
* 判断能否使用指纹
*/
public boolean canUseFingerprint() {
//判断是否是三星手机而且可使用指纹
if (InfoUtil.getBrandName().equals("samsung")) {//判断是否是三星手机
if (FingerPrintUtil.get().isSamsungCanUseFingerPrint(this)) {
return true;
} else {
return false;
}
} else if (InfoUtil.getBrandName().equals("Meizu")
&& InfoUtil.getSDKVersionNumber() < Build.VERSION_CODES.M) {//判断是否是魅族手机
if(FingerPrintUtil.get().isMeizuCanUseFingerPrint()){
return true;
}else{
return false;
}
} else {
if (InfoUtil.getSDKVersionNumber() >= Build.VERSION_CODES.M) {
try {
//捕获异常是否有FingerprintManager这个类
// FingerprintManager mFingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
FingerprintManagerCompat mFingerprintManager = FingerprintManagerCompat.from(this);
boolean hardwareDetected = mFingerprintManager.isHardwareDetected();
if (hardwareDetected) {
return true;
}
} catch (Exception e) {
return false;
}
}
}
return false;
}
/**
* BrandName
* @return
*/
public static String getBrandName(){
String brand = android.os.Build.BRAND;
if (brand == null || brand.length() <= 0) {
return "";
} else {
return brand;
}
}
public class FingerPrintUtil {
private static FingerPrintUtil sFingerPrintUtil;
public static FingerPrintUtil get(){
if(sFingerPrintUtil==null) {
sFingerPrintUtil = new FingerPrintUtil();
}
return sFingerPrintUtil;
}
public boolean isSamsungCanUseFingerPrint(Context context){
Spass mSpass = new Spass();
try {
mSpass.initialize(context);
boolean isFeatureEnabled_fingerprint = mSpass.isFeatureEnabled(Spass.DEVICE_FINGERPRINT);
//判断是否可用指纹
if(isFeatureEnabled_fingerprint){
return true;
}else{
return false;
}
} catch (SsdkUnsupportedException e) {
// log("Exception: " + e);
} catch (UnsupportedOperationException e) {
// log("Fingerprint Service is not supported in the device");
}
return false;
}
public boolean hasSetSamsungFingerPrint(Context context){
SpassFingerprint mSpassFingerprint = new SpassFingerprint(context);
boolean hasEnrolledFingerprints = mSpassFingerprint.hasRegisteredFinger();
return hasEnrolledFingerprints;
}
public boolean isMeizuCanUseFingerPrint(){
try {
FingerprintManager open = FingerprintManager.open();
if (open.isFingerEnable() && open.isSurpport()) {
return true;
} else {
return false;
}
}catch (Exception e){
return false;
}
}
public boolean hasMeizuSetFingerprint(){
try {
FingerprintManager open = FingerprintManager.open();
if(open.getIds()==null){
return false;
}else{
return true;
}
}catch (Exception e){
e.printStackTrace();
}
return false;
}
}
google的指纹监听回掉的使用方法这个网上介绍很多,就不多做注释了:
mCancellationSignal = new CancellationSignal();
mManager.authenticate(null, 0, mCancellationSignal, new FingerprintManagerCompat.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
super.onAuthenticationError(errMsgId, errString);
mFingerprintHint.setText(errString);
if (errString.equals("指纹操作已取消。")) {
cancelFingerPrintDialog();
}
}
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
super.onAuthenticationHelp(helpMsgId, helpString);
mFingerprintHint.setText(helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
cancelFingerPrintDialog();
requestUserInfo();
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
mFingerprintHint.setText("再试一次");
}
}, null);
samsung的指纹识别回掉:
package com.yibairun.presenter;
import android.content.Context;
import com.samsung.android.sdk.pass.Spass;
import com.samsung.android.sdk.pass.SpassFingerprint;
import com.yibairun.contract.FingerPrintContract;
/**
* Created by zhangqingbin on 2017/3/8.
*/
public class SamsungFingerprintImpl {
private final SpassFingerprint mSpassFingerprint;
private final Spass mSpass;
private final Context context;
private final FingerPrintContract.OnSamsungFingerPrintCallBack callBack;
private boolean onReadyIdentify;
public SamsungFingerprintImpl(Context context, SpassFingerprint spassFingerprint, Spass spass, FingerPrintContract.OnSamsungFingerPrintCallBack callBack) {
this.mSpassFingerprint = spassFingerprint;
this.mSpass = spass;
this.context = context;
this.callBack=callBack;
}
private SpassFingerprint.IdentifyListener mIdentifyListenerDialog = new SpassFingerprint.IdentifyListener() {
@Override
public void onFinished(int eventStatus) {
// log("identify finished : reason =" + getEventStatusName(eventStatus));
int FingerprintIndex = 0;
boolean isFailedIdentify = false;
onReadyIdentify = false;
try {
FingerprintIndex = mSpassFingerprint.getIdentifiedFingerprintIndex();
} catch (IllegalStateException ise) {
// log(ise.getMessage());
}
if (eventStatus == SpassFingerprint.STATUS_AUTHENTIFICATION_SUCCESS) {
callBack.onPrintSuccess();
// log("onFinished() : Identify authentification Success with FingerprintIndex : " + FingerprintIndex);
} else if (eventStatus == SpassFingerprint.STATUS_AUTHENTIFICATION_PASSWORD_SUCCESS) {
// log("onFinished() : Password authentification Success");
} else if (eventStatus == SpassFingerprint.STATUS_USER_CANCELLED
|| eventStatus == SpassFingerprint.STATUS_USER_CANCELLED_BY_TOUCH_OUTSIDE) {
// log("onFinished() : User cancel this identify.");
} else if (eventStatus == SpassFingerprint.STATUS_TIMEOUT_FAILED) {
// log("onFinished() : The time for identify is finished.");
callBack.onPrintFailed("识别失败");
} else if (!mSpass.isFeatureEnabled(Spass.DEVICE_FINGERPRINT_AVAILABLE_PASSWORD)) {
if (eventStatus == SpassFingerprint.STATUS_BUTTON_PRESSED) {
// log("onFinished() : User pressed the own button");
// Toast.makeText(mContext, "Please connect own Backup Menu", Toast.LENGTH_SHORT).show();
}
} else {
// log("onFinished() : Authentification Fail for identify");
isFailedIdentify = true;
}
// if (!isFailedIdentify) {
// resetIdentifyIndexDialog();
// }
}
@Override
public void onReady() {
// log("identify state is ready");
}
@Override
public void onStarted() {
// log("User touched fingerprint sensor");
}
@Override
public void onCompleted() {
// log("the identify is completed");
}
};
public void startIdentifyDialog(boolean backup) {
if (onReadyIdentify == false) {
onReadyIdentify = true;
try {
if (mSpassFingerprint != null) {
// setIdentifyIndexDialog();
mSpassFingerprint.startIdentifyWithDialog(context, mIdentifyListenerDialog, backup);
}
} catch (IllegalStateException e) {
onReadyIdentify = false;
// resetIdentifyIndexDialog();
// log("Exception: " + e);
}
} else {
// log("The previous request is remained. Please finished or cancel first");
}
}
}
魅族的指纹识别回掉:
package com.yibairun.presenter;
import com.fingerprints.service.FingerprintManager;
import com.yibairun.contract.FingerPrintContract;
/**
* Created by zhangqingbin on 2017/3/9.
*/
public class MeizuFingerprintImpl {
private final FingerPrintContract.OnMeizuFingerPrintCallBack callBack;
private FingerprintManager.IdentifyCallback mIdentifyCallback;
public MeizuFingerprintImpl(FingerPrintContract.OnMeizuFingerPrintCallBack callBack) {
this.callBack=callBack;
}
FingerprintManager mFM;
private void initFingPrintManager() {
if (mFM == null) {
mFM = FingerprintManager.open(); //调用open方法得到FingerprintManager
}
}
public void startVerify() {
initFingPrintManager(); //得到FingerprintManager实例
if (mFM.getIds() == null) { //得到系统中已经录入的指纹个数
return;
}
if (mIdentifyCallback == null) {
//创建指纹认证回调函数
mIdentifyCallback = createIdentifyCallback();
}
mFM.startIdentify(mIdentifyCallback, mFM.getIds()); //调用指纹认证接口
}
private FingerprintManager.IdentifyCallback createIdentifyCallback() {
return new FingerprintManager.IdentifyCallback() {
@Override
public void onIdentified(int id, boolean updated) { //认证成功
callBack.onMeizuPrintSuccess();
mFM.release(); //认证成功后release, 需要注意的是在不使用指纹功能后必须要调用release, 也就是说open和release严格配对
//否则会造成mBack不能使用, 因为只有调用release之后才能从指纹模式切换到back模式
}
@Override
public void onNoMatch() { //认证失败
// Log.d(TAG, "onNoMatch! ");
callBack.onMeizuPrintFailed("认证失败");
startVerify(); //一次认证失败后重新再次发起认证
}
};
}
}
后续如果有测试机就会尝试兼容其他种类手机,并且补充这篇文章