我尝试使用FingerPrint API构建演示,如下所示:
if (fingerprintManager.hasEnrolledFingerprints()) {
// start fingerprint auth here.
try {
// CryptoObjectHelper cryptoObjectHelper = new CryptoObjectHelper();
if (cancellationSignal == null) {
cancellationSignal = new CancellationSignal();
}
if (cancellationSignal.isCanceled()) {
cancellationSignal = new CancellationSignal();
}
myAuthCallback = new MyAuthCallback(context, handler);
fingerprintManager.authenticate(null, cancellationSignal, 0, myAuthCallback, null);
} catch (Exception e) {
}
}
它在一个活动组件中工作,我可以区分我的指纹。 但是当我尝试使用这些代码使用Service或BroadcastReciver组件时,我无法接收任何回调,FingerPrint API只能在Activity Component中使用它吗?为什么会这样?
答案 0 :(得分:1)
我从源代码中找到了答案,
/frameworks/base/services/core/java/com/android/server/fingerprint/Fingerprint/FingerprintService.java
@Override // Binder call
public void authenticate(final IBinder token, final long opId, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName) {
if (!canUseFingerprint(opPackageName, true /* foregroundOnly */)) {
if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
return;
}
……
private boolean canUseFingerprint(String opPackageName, boolean foregroundOnly) {
checkPermission(USE_FINGERPRINT);
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
if (opPackageName.equals(mKeyguardPackage)) {
return true; // Keyguard is always allowed
}
if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) {
Slog.w(TAG,"Rejecting " + opPackageName + " ; not a current user or profile");
return false;
}
if (mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName)
!= AppOpsManager.MODE_ALLOWED) {
Slog.w(TAG, "Rejecting " + opPackageName + " ; permission denied");
return false;
}
if (foregroundOnly && !isForegroundActivity(uid, pid)) {
Slog.w(TAG, "Rejecting " + opPackageName + " ; not in foreground");
return false;
}
return true;
}
private boolean isForegroundActivity(int uid, int pid) {
try {
List<RunningAppProcessInfo> procs =
ActivityManagerNative.getDefault().getRunningAppProcesses();
int N = procs.size();
for (int i = 0; i < N; i++) {
RunningAppProcessInfo proc = procs.get(i);
if (proc.pid == pid && proc.uid == uid
&& proc.importance == IMPORTANCE_FOREGROUND) {
return true;
}
}
} catch (RemoteException e) {
Slog.w(TAG, "am.getRunningAppProcesses() failed");
}
return false;
}
要求前台活动进行身份验证!!