下面列出了怎么用android.hardware.fingerprint.FingerprintManager的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void testAuthenticationError() throws Exception {
when(fingerprintApiWrapper.isUnavailable()).thenReturn(false);
when(fingerprintApiWrapper.getFingerprintManager()).thenReturn(fingerprintManager);
TestObserver<FingerprintAuthenticationResult> testObserver = observable.test();
ArgumentCaptor<FingerprintManager.AuthenticationCallback> callbackCaptor = ArgumentCaptor.forClass(FingerprintManager.AuthenticationCallback.class);
verify(fingerprintManager).authenticate(any(CryptoObject.class), any(CancellationSignal.class), anyInt(), callbackCaptor.capture(), any(Handler.class));
callbackCaptor.getValue().onAuthenticationError(0, ERROR_MESSAGE);
testObserver.awaitTerminalEvent();
testObserver.assertError(FingerprintAuthenticationException.class);
testObserver.assertValueCount(0);
assertTrue("Should contain 1 error", testObserver.errorCount() == 1);
Throwable throwable = testObserver.errors().get(0);
assertTrue("Message should equal ERROR_MESSAGE", throwable.getMessage().equals(ERROR_MESSAGE));
}
/**
* Called when we get notification from fingerprint HAL that an image has been acquired.
* Common to authenticate and enroll.
* @param acquiredInfo info about the current image acquisition
* @return true if client should be removed
*/
public boolean onAcquired(int acquiredInfo, int vendorCode) {
if (mReceiver == null)
return true; // client not connected
try {
mReceiver.onAcquired(getHalDeviceId(), acquiredInfo, vendorCode);
return false; // acquisition continues...
} catch (RemoteException e) {
Slog.w(TAG, "Failed to invoke sendAcquired:", e);
return true; // client failed
} finally {
// Good scans will keep the device awake
if (acquiredInfo == FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
notifyUserActivity();
}
}
}
@Test
public void testAuthenticationSuccessful() throws Exception {
when(fingerprintApiWrapper.isUnavailable()).thenReturn(false);
when(fingerprintApiWrapper.getFingerprintManager()).thenReturn(fingerprintManager);
AuthenticationResult result = mock(AuthenticationResult.class);
TestObserver<FingerprintAuthenticationResult> testObserver = observable.test();
ArgumentCaptor<FingerprintManager.AuthenticationCallback> callbackCaptor = ArgumentCaptor.forClass(FingerprintManager.AuthenticationCallback.class);
verify(fingerprintManager).authenticate(any(CryptoObject.class), any(CancellationSignal.class), anyInt(), callbackCaptor.capture(), any(Handler.class));
callbackCaptor.getValue().onAuthenticationSucceeded(result);
testObserver.awaitTerminalEvent();
testObserver.assertNoErrors();
testObserver.assertComplete();
testObserver.assertValueCount(1);
FingerprintAuthenticationResult fingerprintAuthenticationResult = testObserver.values().get(0);
assertTrue("Authentication should be successful", fingerprintAuthenticationResult.isSuccess());
assertTrue("Result should be equal AUTHENTICATED", fingerprintAuthenticationResult.getResult().equals(FingerprintResult.AUTHENTICATED));
assertTrue("Should contain no message", fingerprintAuthenticationResult.getMessage() == null);
}
@Override // binder call
public void onDialogDismissed(int reason) {
if (mBundle != null && mDialogReceiverFromClient != null) {
try {
mDialogReceiverFromClient.onDialogDismissed(reason);
if (reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL) {
onError(FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED,
0 /* vendorCode */);
}
mDialogDismissed = true;
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify dialog dismissed", e);
}
stop(true /* initiatedByClient */);
}
}
@Override
public int start() {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "enroll: no fingerprint HAL!");
return ERROR_ESRCH;
}
final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
try {
final int result = daemon.enroll(mCryptoToken, getGroupId(), timeout);
if (result != 0) {
Slog.w(TAG, "startEnroll failed, result=" + result);
MetricsLogger.histogram(getContext(), "fingerprintd_enroll_start_error", result);
onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
return result;
}
} catch (RemoteException e) {
Slog.e(TAG, "startEnroll failed", e);
}
return 0; // success
}
@Override
public int stop(boolean initiatedByClient) {
if (mAlreadyCancelled) {
Slog.w(TAG, "stopEnroll: already cancelled!");
return 0;
}
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "stopEnrollment: no fingerprint HAL!");
return ERROR_ESRCH;
}
try {
final int result = daemon.cancel();
if (result != 0) {
Slog.w(TAG, "startEnrollCancel failed, result = " + result);
return result;
}
} catch (RemoteException e) {
Slog.e(TAG, "stopEnrollment failed", e);
}
if (initiatedByClient) {
onError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, 0 /* vendorCode */);
}
mAlreadyCancelled = true;
return 0;
}
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;
}
@RequiresApi(api = Build.VERSION_CODES.M)
public void setupFingerprintStuff() {
fingerprintManager = (FingerprintManager) this.getSystemService(Context.FINGERPRINT_SERVICE);
fingerprintHelper = new FingerprintHelper(this);
try {
generateKey();
if (cipherInit()) {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
fingerprintHelper.startAuth(fingerprintManager, cryptoObject);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public PublishSubject<Boolean> begin() {
if(publishSubject == null){
publishSubject = PublishSubject.create();
}
if (Build.VERSION.SDK_INT < 23){
publishSubject.onError(new FPerException(SYSTEM_API_ERROR));
}else {
initManager();
confirmFinger();
try {
CryptoObjectHelper helper = new CryptoObjectHelper();
FingerprintManager.CryptoObject cryptoObject = helper.buildCryptoObject();
startListening(cryptoObject);
} catch (Exception e) {
e.printStackTrace();
}
// startListening(null);
}
return publishSubject;
}
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
System.out.println("Error " + errorCode + " : " + errString);
NSError error;
switch (errorCode) {
case FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE:
error = new NSError(LAErrorDomain, LAError.TouchIDNotAvailable, getUserInfo(errString.toString()));
break;
case FingerprintManager.FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
error = new NSError(LAErrorDomain, LAError.AuthenticationFailed, getUserInfo(errString.toString()));
break;
case FingerprintManager.FINGERPRINT_ERROR_TIMEOUT:
error = new NSError(LAErrorDomain, LAError.SystemCancel, getUserInfo(errString.toString()));
break;
case FingerprintManager.FINGERPRINT_ERROR_CANCELED:
error = new NSError(LAErrorDomain, LAError.SystemCancel, getUserInfo(errString.toString()));
break;
case FingerprintManager.FINGERPRINT_ERROR_LOCKOUT:
error = new NSError(LAErrorDomain, LAError.TouchIDLockout, getUserInfo(errString.toString()));
}
}
@Test
@Config(sdk = Build.VERSION_CODES.P)
public void testVerifySecureHardwareAvailability_api28() throws Exception {
ReactApplicationContext context = getRNContext();
// for api24+ system feature should be enabled
shadowOf(context.getPackageManager()).setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true);
// set that hardware is available and fingerprints configured
final FingerprintManager fm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
shadowOf(fm).setIsHardwareDetected(true);
shadowOf(fm).setDefaultFingerprints(5); // 5 fingerprints are available
int result = BiometricManager.from(context).canAuthenticate();
assertThat(result, is(BiometricManager.BIOMETRIC_SUCCESS));
final CipherStorage storage = new CipherStorageKeystoreAesCbc();;
// expected RsaEcb with fingerprint
assertThat(storage.supportsSecureHardware(), is(true));
}
private static FingerprintManager.AuthenticationCallback wrapCallback(
final AuthenticationCallback callback) {
return new FingerprintManager.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
callback.onAuthenticationError(errMsgId, errString);
}
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
callback.onAuthenticationHelp(helpMsgId, helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
callback.onAuthenticationSucceeded(new AuthenticationResultInternal(
unwrapCryptoObject(result.getCryptoObject())));
}
@Override
public void onAuthenticationFailed() {
callback.onAuthenticationFailed();
}
};
}
public void startAuth(FingerprintManager manager,
FingerprintManager.CryptoObject cryptoObject) {
cancellationSignal = new CancellationSignal();
if (ActivityCompat.checkSelfPermission(appContext,
Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(appContext,
appContext.getString(R.string.fingerprint_error_no_permission),
Toast.LENGTH_LONG).show();
return;
}
manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);
}
private static FingerprintManager fingerprintUnlockSupported(Context ctx)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return null;
}
if (ctx.checkSelfPermission(Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
return null;
}
FingerprintManager fpManager = (FingerprintManager) ctx.getSystemService(Context.FINGERPRINT_SERVICE);
if (fpManager == null || !fpManager.isHardwareDetected() || !fpManager.hasEnrolledFingerprints()) {
return null;
}
return fpManager;
}
@Test
public void testAuthenticationHelp() throws Exception {
when(fingerprintApiWrapper.isUnavailable()).thenReturn(false);
when(fingerprintApiWrapper.getFingerprintManager()).thenReturn(fingerprintManager);
TestObserver<FingerprintAuthenticationResult> testObserver = observable.test();
ArgumentCaptor<FingerprintManager.AuthenticationCallback> callbackCaptor = ArgumentCaptor.forClass(FingerprintManager.AuthenticationCallback.class);
verify(fingerprintManager).authenticate(any(CryptoObject.class), any(CancellationSignal.class), anyInt(), callbackCaptor.capture(), any(Handler.class));
callbackCaptor.getValue().onAuthenticationHelp(0, MESSAGE_HELP);
testObserver.assertNotTerminated();
testObserver.assertNoErrors();
testObserver.assertNotComplete();
testObserver.assertValueCount(1);
FingerprintAuthenticationResult fingerprintAuthenticationResult = testObserver.values().get(0);
assertTrue("Authentication should not be successful", !fingerprintAuthenticationResult.isSuccess());
assertTrue("Result should be equal HELP", fingerprintAuthenticationResult.getResult().equals(FingerprintResult.HELP));
assertTrue("Should contain help message", fingerprintAuthenticationResult.getMessage().equals(MESSAGE_HELP));
}
@Test
@Config(sdk = Build.VERSION_CODES.P)
public void testFingerprintConfigured_api28() throws Exception {
// GIVEN:
// API28 android version
// for api24+ system feature should be enabled
// fingerprints are configured
ReactApplicationContext context = getRNContext();
shadowOf(context.getPackageManager()).setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true);
// set that hardware is available
FingerprintManager fm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
shadowOf(fm).setIsHardwareDetected(true);
shadowOf(fm).setDefaultFingerprints(5); // 5 fingerprints are available
// WHEN: verify availability
final int result = BiometricManager.from(context).canAuthenticate();
final KeychainModule module = new KeychainModule(context);
final boolean isFingerprintWorking = module.isFingerprintAuthAvailable();
// THEN: biometrics works
assertThat(result, is(BiometricManager.BIOMETRIC_SUCCESS));
assertThat(isFingerprintWorking, is(true));
}
@RequiresApi(Build.VERSION_CODES.M)
private static Whorlwind createRealWhorlwind(Context context, Storage storage, String keyAlias) {
try {
FingerprintManager fingerprintManager = context.getSystemService(FingerprintManager.class);
if (fingerprintManager == null) {
Log.w(TAG, "No fingerprint manager.");
return new NullWhorlwind();
}
if (!isHardwareDetected(fingerprintManager)) return new NullWhorlwind();
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null); // Ensure the key store can be loaded before continuing.
KeyPairGenerator keyGenerator =
KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RealWhorlwind.createCipher(); // If this doesn't throw, the cipher we need is available.
return new RealWhorlwind(context, fingerprintManager, storage, keyAlias, keyStore,
keyGenerator, keyFactory);
} catch (Exception e) {
Log.w(TAG, "Cannot store securely.", e);
return new NullWhorlwind();
}
}
FingerprintAuthOnSubscribe(FingerprintManager fingerprintManager, Storage storage,
String name, AtomicBoolean readerScanning, Object dataLock, RealWhorlwind whorlwind) {
this.fingerprintManager = fingerprintManager;
this.storage = storage;
this.name = name;
this.readerScanning = readerScanning;
this.dataLock = dataLock;
// TODO: Come up with a better way to access the required data without passing this in.
this.whorlwind = whorlwind;
}
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void processAuthentication(FingerprintManager.CryptoObject cryptObj) {
FidoSigner fidoSigner = new FidoSignerAndroidM(cryptObj.getSignature());
// fido signer doesn't need key pair, handled internally
String msg = authOp.auth(authReq, fidoSigner, null);
returnResultAndFinish(msg);
}
public static boolean hasDeviceFingerprintSupport(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
return false;
}
return fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints();
} else {
return false;
}
}
@TargetApi(Build.VERSION_CODES.M)
private void initManager() {
mCancellationSignal = new CancellationSignal();
manager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
mKeyManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
mSelfCancelled = new FingerprintManager.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
//多次指纹密码验证错误后,进入此方法;并且,不能短时间内调用指纹验证
publishSubject.onError(new FPerException(FINGERPRINTERS_FAILED_ERROR));
mCancellationSignal.cancel();
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
publishSubject.onNext(true);
}
@Override
public void onAuthenticationFailed() {
publishSubject.onNext(false);
}
};
}
public static boolean isDeviceSupported(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return false;
}
FingerprintManager fingerprintManager = context.getSystemService(FingerprintManager.class);
KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
return (keyguardManager != null) && (fingerprintManager != null) &&
keyguardManager.isKeyguardSecure() &&
fingerprintManager.isHardwareDetected() &&
fingerprintManager.hasEnrolledFingerprints();
}
public AuthenticationClient(Context context, long halDeviceId, IBinder token,
IFingerprintServiceReceiver receiver, int targetUserId, int groupId, long opId,
boolean restricted, String owner, Bundle bundle,
IBiometricPromptReceiver dialogReceiver, IStatusBarService statusBarService) {
super(context, halDeviceId, token, receiver, targetUserId, groupId, restricted, owner);
mOpId = opId;
mBundle = bundle;
mDialogReceiverFromClient = dialogReceiver;
mStatusBarService = statusBarService;
mFingerprintManager = (FingerprintManager) getContext()
.getSystemService(Context.FINGERPRINT_SERVICE);
}
@Override
public void onAuthenticationSucceeded(final FingerprintManager.AuthenticationResult result) {
mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
mIcon.setImageResource(R.drawable.ic_fingerprint_success);
mErrorTextView.setTextColor(
mErrorTextView.getResources().getColor(R.color.success_color, null));
mErrorTextView.setText(
mErrorTextView.getResources().getString(R.string.fingerprint_success));
mIcon.postDelayed(new Runnable() {
@Override
public void run() {
mCallback.onAuthenticated(result.getCryptoObject());
}
}, SUCCESS_DELAY_MILLIS);
}
/**
* Proceed the purchase operation
*
* @param withFingerprint {@code true} if the purchase was made by using a fingerprint
* @param cryptoObject the Crypto object
*/
public void onPurchased(boolean withFingerprint,
@Nullable FingerprintManager.CryptoObject cryptoObject) {
if (withFingerprint) {
// If the user has authenticated with fingerprint, verify that using cryptography and
// then show the confirmation message.
assert cryptoObject != null;
tryEncrypt(cryptoObject.getCipher());
} else {
// Authentication happened with backup password. Just show the confirmation message.
showConfirmation(null);
}
}
@Override
public void onAuthenticated(FingerprintManager.AuthenticationResult result) {
// Callback from FingerprintUiHelper. Let the activity know that authentication was
// successful.
callbackOnAuthenticated(result);
dismissDialog();
}
@Override
public FingerprintManager createService(ContextImpl ctx) throws ServiceNotFoundException {
final IBinder binder;
if (ctx.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
binder = ServiceManager.getServiceOrThrow(Context.FINGERPRINT_SERVICE);
} else {
binder = ServiceManager.getService(Context.FINGERPRINT_SERVICE);
}
IFingerprintService service = IFingerprintService.Stub.asInterface(binder);
return new FingerprintManager(ctx.getOuterContext(), service);
}
@Override
public void onAuthenticated(FingerprintManager.AuthenticationResult result) {
// Callback from FingerprintUiHelper. Let the activity know that authentication was
// successful.
FingerprintAuth.onAuthenticated(true /* withFingerprint */, result);
dismissAllowingStateLoss();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().setTitle(getString(R.string.authenticate));
View v = inflater.inflate(R.layout.fingerprint_dialog_container, container, false);
mCancelButton = (Button) v.findViewById(R.id.cancel_button);
mCancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
mFingerprintContent = v.findViewById(R.id.fingerprint_container);
mFingerprintInfoTextView = (TextView)
v.findViewById(R.id.fingerprint_info_text);
mFingerprintUiHelper = new FingerprintUiHelper(
mActivity.getSystemService(FingerprintManager.class),
(ImageView) v.findViewById(R.id.fingerprint_icon),
(TextView) v.findViewById(R.id.fingerprint_status), this);
updateStage();
// If fingerprint authentication is not available, switch immediately to the backup
// (password) screen.
if (!mFingerprintUiHelper.isFingerprintAuthAvailable()) {
goToBackup();
}
return v;
}
@RequiresApi(api = Build.VERSION_CODES.M)
public static boolean checkFinger(Context ctx) {
// Keyguard Manager
KeyguardManager keyguardManager = (KeyguardManager) ctx.getSystemService(KEYGUARD_SERVICE);
// Fingerprint Manager
FingerprintManager fingerprintManager = (FingerprintManager) ctx.getSystemService(FINGERPRINT_SERVICE);
try {
// Check if the fingerprint sensor is present
if (!fingerprintManager.isHardwareDetected()) {
// Update the UI with a message
StringUtils.showToast(ctx, ctx.getString(R.string.fp_not_supported));
return false;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
StringUtils.showToast(ctx, ctx.getString(R.string.fp_not_configured));
return false;
}
if (!keyguardManager.isKeyguardSecure()) {
StringUtils.showToast(ctx, ctx.getString(R.string.fp_not_enabled_sls));
return false;
}
} catch (SecurityException se) {
se.printStackTrace();
}
return true;
}