在android6.0之后谷歌对指纹识别进行了官方支持,今天还在放假,所以就随意尝试了一下这个api,但是遇到了各种各样的问题
①在使用FingerPrintManager这个类实现的时候发现了很多问题,这个类里面的一些函数是被hide了的,也就是我们不能调用,比如enroll(),也就是说,当前的官方支持其实是有限的,我们能读取到本机已经存在的指纹(用于解锁的),然后验证这些指纹,但是不能让用户在app使用的时候录入一个指纹,用于app的其他功能,这个是一个缺陷吧目前来说,下面的图也是展示了识别一个可以用来解锁的指纹的功能。
②使用FingerPrintManager的时候会遇到要在应用中判断权限的问题,不清楚是因为android M要求的还是api需要,调用的时候也没有反应,既没有功能,也没有提示给予权限,原因有待查证。
③在一顿尝试无果之后发现了两个特别的类,一个叫做FingerPrintManagerCompat,这是一个兼容的FingerPrint操作类,还有一个类似的叫做FingerPrintManagerCompatApi23,使用这两个类也能实现到识别指纹的功能,但是也是有局限的,如①所说的。这两个类都能实现这个效果,但是需要API Level 23,如果达不到不会报错,这些类会什么都不做。
展示图,因为没有真机,所以只能用模拟器调试一下,这里也只能用官方的,Genymotion免费版貌似不能模拟指纹:
直接上代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private Button check;
private FingerprintManagerCompat manager; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); check = (Button) findViewById(R.id.btn_check); check.setOnClickListener(this); // 获取一个FingerPrintManagerCompat的实例
manager = FingerprintManagerCompat.from(this);
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_check:
/**
* 开始验证,什么时候停止由系统来确定,如果验证成功,那么系统会关系sensor,如果失败,则允许
* 多次尝试,如果依旧失败,则会拒绝一段时间,然后关闭sensor,过一段时候之后再重新允许尝试
*
* 第四个参数为重点,需要传入一个FingerprintManagerCompat.AuthenticationCallback的子类
* 并重写一些方法,不同的情况回调不同的函数
*/
manager.authenticate(null, 0, null, new MyCallBack(), null);
break;
}
} public class MyCallBack extends FingerprintManagerCompat.AuthenticationCallback {
private static final String TAG = "MyCallBack"; // 当出现错误的时候回调此函数,比如多次尝试都失败了的时候,errString是错误信息
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
Log.d(TAG, "onAuthenticationError: " + errString);
} // 当指纹验证失败的时候会回调此函数,失败之后允许多次尝试,失败次数过多会停止响应一段时间然后再停止sensor的工作
@Override
public void onAuthenticationFailed() {
Log.d(TAG, "onAuthenticationFailed: " + "验证失败");
} @Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Log.d(TAG, "onAuthenticationHelp: " + helpString);
} // 当验证的指纹成功时会回调此函数,然后不再监听指纹sensor
@Override
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult
result) {
Log.d(TAG, "onAuthenticationSucceeded: " + "验证成功");
}
} }
有博友提出了问题,这里记录下:
1.如何让失败或者成功之后Sensor继续保持监听新的指纹?
答:因为API较新的缘故,这个兼容的Manager类还不能做到自动重启的功能,但是我们可以自己写一个。因为Api中规定了如果回调了Error或者Succeed方法之后,sensor会被关闭,直到下一次重新调用authenticate方法授权,但是我们不能在Error或Succeed直接调用这个方法,因为处于安全性的考虑,不允许开发者短时间内连续授权,经过粗略的测试,android允许我们在30s之后重新打开Sensor授权监听,所以我们要做的,就是通过Handler的sendMessageDelayed方法发送一个延迟的消息,再在Handler中重新调用authenticate方法,具体的代码如下:
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, "handleMessage: 重启指纹模块");
manager.authenticate(null, 0, null, new MyCallBack(), handler);
}
};
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
handler.sendMessageDelayed(new Message(), 1000 * 30);
Log.d(TAG, "onAuthenticationError: " + errString);
} @Override
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
handler.sendMessageDelayed(new Message(), 1000 * 30);
Log.d(TAG, "onAuthenticationSucceeded: " + "验证成功");
}
2.为什么6.0以下的一些带指纹手机可以用FingerprintManager来操作指纹,而没有指纹的手机会崩溃。
这个估计时因为某些厂商(小米、vivo等)的指纹识别机器的Rom中添加了FingerprintManager的API,实际上这个API是在6.0才加入的。文档:
这就导出了一个问题:如果我要给6.0以下或者没有适配6.0指纹的手机进行指纹操作的时候,要怎么做?
使用FingerprintManagerCompat肯定是不行的,因为文档也说了,低于M的系统版本,FingerprintManagerCompat无论手机是否有指纹识别模块,均认为没有指纹识别。那么我们实际上是可以用FingerprintManager来做的,因为小米等厂商已经把API加进去了(这里要充分测试,毕竟不是官方的api)。
在工程中,使用下面代码来获得一个FingerprintManager:
FingerprintManager manager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
这个地方要保证你的CompleteSdkVersion版本要大于23,否则IDE也找不到这个类。
接着,假设我们要检查手机是否支持指纹识别:
manager.hasEnrolledFingerprints();
这个时候,如果你的App需要在6.0的及以上的平台运行,还需要进行运行时权限检查,代码如下:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) !=
PackageManager.PERMISSION_GRANTED) {
manager.hasEnrolledFingerprints();
return;
}
到了这里,Studio中还会提示,这个方法要添加注解,表明在6.0及以上的平台中才能使用:
而实际上,我们不能添加这个注解,因为我们不仅仅要给6.0及以上的平台使用,还要给6.0以下的平台使用,那么我们可以直接选中第4行的Disable inspection来忽略这个错误。
当我们把APP安装到手机中的时候,如果手机没有指纹识别模块,APP就会Crash,Log中会显示ClassNotFoundException,而在低版本带指纹识别的机器上运行却没有问题。这就佐证了我们一开始说到的,厂商的Rom中,没有指纹识别的手机并不会添加对应的API,所以自然会提示找不到该类。
那么我们究竟怎么用到这个FingerprintManager类呢?
很简单,在Application中先进行判断,通过反射来检查是否存在该类,然后把结果保存起来:
public class MyApplication extends Application {
public static final String HAS_FINGERPRINT_API = "hasFingerPrintApi";
public static final String SETTINGS = "settings"; @Override
public void onCreate() {
super.onCreate();
SharedPreferences sp = getSharedPreferences(SETTINGS, MODE_PRIVATE);
if (sp.contains(HAS_FINGERPRINT_API)) { // 检查是否存在该值,不必每次都通过反射来检查
return;
}
SharedPreferences.Editor editor = sp.edit();
try {
Class.forName("android.hardware.fingerprint.FingerprintManager"); // 通过反射判断是否存在该类
editor.putBoolean(HAS_FINGERPRINT_API, true);
} catch (ClassNotFoundException e) {
editor.putBoolean(HAS_FINGERPRINT_API, false);
e.printStackTrace();
}
editor.apply();
}
}
其他地方只需要将该值取出判断即可。
试了一下身边的几个手机,小米支持,乐视不支持。
3.怎么取消监听?
很简单,authenticate方法中的第二个参数是一个CancellationSignal对象,这个对象是用来维护取消操作的,这些操作包括取消监听和设定取消回调等。所以,如果要取消,这个参数就不能是null,可以把代码稍作修改:
在Activity中添加一个CancellationSignal变量:
private CancellationSignal mCancellationSignal = new CancellationSignal();
接着,在要验证的时候传入这个对象,在要取消的时候,调用这个对象的cancel方法即可:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start:
if (mCancellationSignal.isCanceled()) {
mCancellationSignal = new CancellationSignal();
}
mFingerprintManagerCompat.authenticate(null, 0, mCancellationSignal, new MyCallBack(), null);
break;
case R.id.stop:
mCancellationSignal.cancel();
break;
}
}
Android开发学习之路-指纹识别api的更多相关文章
-
Android开发学习之路--Android系统架构初探
环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...
-
Android开发学习之路-RecyclerView滑动删除和拖动排序
Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...
-
Android开发学习之路--基于vitamio的视频播放器(二)
终于把该忙的事情都忙得差不多了,接下来又可以开始good good study,day day up了.在Android开发学习之路–基于vitamio的视频播放器(一)中,主要讲了播放器的界面的 ...
-
Android开发学习之路--Android Studio cmake编译ffmpeg
最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...
-
Android开发学习之路--网络编程之xml、json
一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...
-
Android开发学习之路--Activity之初体验
环境也搭建好了,android系统也基本了解了,那么接下来就可以开始学习android开发了,相信这么学下去肯定可以把android开发学习好的,再加上时而再温故下linux下的知识,看看androi ...
-
Android开发学习之路--MAC下Android Studio开发环境搭建
自从毕业开始到现在还没有系统地学习android应用的开发,之前一直都是做些底层的驱动,以及linux上的c开发.虽然写过几个简单的app,也对android4.0.3的源代码做过部分的分析,也算入门 ...
-
Android开发学习之路-该怎么学Android(Service和Activity通信为例)
在大部分地方,比如书本或者学校和培训机构,教学Android的方式都基本类似,就是告诉先上原理方法,然后对着代码讲一下. 但是,这往往不是一个很好的方法,为什么? ① 学生要掌握这个方法的用途,只能通 ...
-
Android开发学习之路-记一次CSDN公开课
今天的CSDN公开课Android事件处理重难点快速掌握中老师讲到一个概念我觉得不正确. 原话是这样的:点击事件可以通过事件监听和回调两种方法实现. 我一听到之后我的表情是这样的: 这跟我学的看的都不 ...
随机推荐
-
Python 3.5源码编译安装
系统环境:CentOS 6.8-Minimal 安装Python依赖包: [root@Python src]# yum install zlib-devel bzip2-devel openssl-d ...
-
git入门操作命令(转载)
以下为git环境搭建: 先建用户-->建组-->用户添加到组 新建项目,命名空间选择组 项目建完后,会分配远端地址. 然后本地配置好远端地址后,提交代码. 设置用户,邮箱 git ...
-
【原创】tcp协议那块一些点(想到了再加)
1.3次握手 4次握手 2.那张状态图,FIN_WAIT主动关闭方,CLOSE_WAIT被动关闭方 主动关闭方发出FIN后进入FIN_WAIT,FIN_WAIT方收到了ACK和FIN,发出了ACK,则 ...
-
[C++知识点]2015.4.18
1.“static_cast/强制转换”后普通函数.虚函数的表现 A基类 B子类 实例aPtr:将B实例强制抓换得到的A实例 实例bPtr:将A实例强制转换得到的B实例 总结: (1) aPtr因为是 ...
-
android ORMlite的应用
ORMLite -轻量级的对象关系映射(ORM) 如果你需要在android中使用ORMLite 你需要进入官方网站http://ormlite.com/ 中下载 下载了这两个包以后,你还需要在对应的 ...
-
DB Query Analyzer 5.05 is released, 65 articles concerned have been published
DB Query Analyzer 5.05 is released, 65 articles concerned have been published DB Query Analyzer is p ...
-
idea: Unable to parse template ";class";
使用idea创建文件时,报“Cannot Create Class”.具体错误为: Unable to parse template "Class" error meesage: ...
-
Delphi中 弹出框的用法
Delphi中的提示框有 Application.MessageBox ShowMessage messagedlg 个人认为 相对来说 Application.MessageBox 更加灵活 也相 ...
-
20170908工作日记--UML画类图、HTTP协议、Volley源码走读
随手搜了一下,Android studio居然能够自动帮追我们生成UML的类图,简直太棒了http://www.gcssloop.com/course/UsePlantUMLInAS(Win),具体做 ...
-
JavaWeb之Servlet中ServletConfig和ServletContext
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html [正文] 一.ServletConfig:代表当前 ...