下面列出了怎么用android.hardware.biometrics.BiometricPrompt的API类实例代码及写法,或者点击链接到github查看源代码。
@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 // binder call
public void onError(long deviceId, int error, int vendorCode) {
if (mExecutor != null) {
// BiometricPrompt case
if (error == FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED
|| error == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
// User tapped somewhere to cancel, or authentication was cancelled by the app
// or got kicked out. The prompt is already gone, so send the error immediately.
mExecutor.execute(() -> {
sendErrorResult(deviceId, error, vendorCode);
});
} else {
// User got an error that needs to be displayed on the dialog, post a delayed
// runnable on the FingerprintManager handler that sends the error message after
// FingerprintDialog.HIDE_DIALOG_DELAY to send the error to the application.
mHandler.postDelayed(() -> {
mExecutor.execute(() -> {
sendErrorResult(deviceId, error, vendorCode);
});
}, BiometricPrompt.HIDE_DIALOG_DELAY);
}
} else {
mHandler.obtainMessage(MSG_ERROR, error, vendorCode, deviceId).sendToTarget();
}
}
@TargetApi(Build.VERSION_CODES.P)
private void showFingerprintDialog(@NonNull final AuthenticationCallback authenticationCallback) {
new BiometricPrompt.Builder(mContext)
.setTitle(mTitle)
.setSubtitle(mSubTitle)
.setDescription(mDescription)
.setNegativeButton(mButtonTitle,
mContext.getMainExecutor(),
new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialogInterface, final int i) {
authenticationCallback.authenticationCanceledByUser();
}
})
.build()
.authenticate(new CancellationSignal(),
mContext.getMainExecutor(),
new AuthenticationCallbackV28(authenticationCallback));
}
@TargetApi(Build.VERSION_CODES.P)
private void displayBiometricPrompt(final BiometricCallback biometricCallback) {
if (initCipher()) {
bioCryptoObject = new BiometricPrompt.CryptoObject(cipher);
new BiometricPrompt.Builder(context)
.setTitle(title)
.setSubtitle(subtitle)
.setDescription(description)
.setNegativeButton(negativeButtonText, context.getMainExecutor(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
biometricCallback.onAuthenticationCancelled();
}
})
.build()
.authenticate(bioCryptoObject, mCancellationSignal, context.getMainExecutor(),
new BiometricCallbackV28(biometricCallback));
}
}
private void doLoginBiometric() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) return;
BioAuthenticationCallback biometricCallback =
new BioAuthenticationCallback(LoginActivity.this.getApplicationContext(), () ->
handler.post(() -> doLogin(false, useCps, false))
);
BiometricPrompt bioPrompt = new BiometricPrompt.Builder(this)
.setTitle(getString(R.string.login_title))
.setSubtitle(mSqrlMatcher.group(1))
.setDescription(getString(R.string.login_verify_domain_text))
.setNegativeButton(
getString(R.string.button_cps_cancel),
this.getMainExecutor(),
(dialogInterface, i) -> {}
).build();
CancellationSignal cancelSign = new CancellationSignal();
cancelSign.setOnCancelListener(() -> {});
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyStore.Entry entry = keyStore.getEntry("quickPass", null);
Cipher decCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); //or try with "RSA"
decCipher.init(Cipher.DECRYPT_MODE, ((KeyStore.PrivateKeyEntry) entry).getPrivateKey());
bioPrompt.authenticate(new BiometricPrompt.CryptoObject(decCipher), cancelSign, this.getMainExecutor(), biometricCallback);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
try {
BiometricPrompt.CryptoObject co = result.getCryptoObject();
SQRLStorage.getInstance(context).decryptIdentityKeyBiometric(co.getCipher());
new Thread(doneCallback).start();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @see BiometricPrompt.AuthenticationCallback#onAuthenticationError(int, CharSequence)
*/
@Override
public void onAuthenticationError(final int errorCode, final CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
switch (errorCode) {
//User canceled the scanning process by pressing the negative button.
case BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED:
mCallback.authenticationCanceledByUser();
break;
// Device doesn't have the supported fingerprint hardware.
case BiometricPrompt.BIOMETRIC_ERROR_HW_NOT_PRESENT:
case BiometricPrompt.BIOMETRIC_ERROR_HW_UNAVAILABLE:
mCallback.fingerprintAuthenticationNotSupported();
break;
//User did not register any fingerprints.
case BiometricPrompt.BIOMETRIC_ERROR_NO_BIOMETRICS:
mCallback.hasNoFingerprintEnrolled();
break;
//Any other unrecoverable error
default:
mCallback.onAuthenticationError(errorCode, errString);
}
}
@SuppressLint("NewApi")
@NonNull
public BiometricPromptCompat build() {
if (title == null) {
throw new IllegalArgumentException("You should set a title for BiometricPrompt.");
}
if (isApiPSupported()) {
BiometricPrompt.Builder builder = new BiometricPrompt.Builder(context);
builder.setTitle(title);
if (subtitle != null) {
builder.setSubtitle(subtitle);
}
if (description != null) {
builder.setDescription(description);
}
if (negativeButtonText != null) {
builder.setNegativeButton(
negativeButtonText, context.getMainExecutor(), negativeButtonListener);
}
return new BiometricPromptCompat(
new BiometricPromptApi28Impl(context, builder.build())
);
} else {
return new BiometricPromptCompat(
new BiometricPromptApi23Impl(
context, title, subtitle, description,
negativeButtonText, negativeButtonListener
)
);
}
}
private static BiometricPrompt.CryptoObject toCryptoObjectApi28(
@Nullable BiometricPromptCompat.ICryptoObject ico
) {
if (ico == null) {
return null;
} else if (ico.getCipher() != null) {
return new BiometricPrompt.CryptoObject(ico.getCipher());
} else if (ico.getMac() != null) {
return new BiometricPrompt.CryptoObject(ico.getMac());
} else if (ico.getSignature() != null) {
return new BiometricPrompt.CryptoObject(ico.getSignature());
} else {
throw new IllegalArgumentException("ICryptoObject doesn\'t include any data.");
}
}
private void showBiometricPromptCompat(FragmentActivity activity, FingerprintDialogCallbacks callback) {
androidx.biometric.BiometricPrompt.PromptInfo promptInfo = new androidx.biometric.BiometricPrompt.PromptInfo.Builder()
.setTitle(activity.getString(R.string.fingerprint_alert_title))
.setNegativeButtonText(activity.getString(R.string.cancel))
.build();
androidx.biometric.BiometricPrompt biometricPrompt = new androidx.biometric.BiometricPrompt(activity, Executors.newSingleThreadExecutor(), new androidx.biometric.BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
if (errorCode == androidx.biometric.BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
callback.onFingerprintCancel();
} else {
callback.onFingerprintError(errString.toString());
}
}
@Override
public void onAuthenticationSucceeded(@NonNull androidx.biometric.BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
callback.onFingerprintSuccess(null);
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
activity.runOnUiThread(() -> Toast.makeText(activity, "Fingerprint not recognized. Try again", Toast.LENGTH_SHORT).show());
}
});
biometricPrompt.authenticate(promptInfo);
}
private void biometricPromptTest() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
BiometricPrompt bp = new BiometricPrompt.Builder(this)
.setTitle("Authenticate Test")
.setDescription("setDescription")
.setNegativeButton(getString(android.R.string.cancel), getMainExecutor(), (dialogInterface, i) -> print("canceled"))
.setSubtitle("setSubtitle")
.build();
CancellationSignal signal = new CancellationSignal();
signal.setOnCancelListener(() -> print("canceled from CancellationSignal"));
bp.authenticate(signal, getMainExecutor(), new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
print("onAuthenticationError:" + varArgsToString(errorCode, errString));
}
@Override
public void onAuthenticationFailed() {
print("onAuthenticationFailed");
finish();
}
@Override
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
print("onAuthenticationSucceeded");
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
print("onAuthenticationHelp:" + varArgsToString(helpCode, helpString));
}
});
new Timer().schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(signal::cancel);
}
}, 5000);
}
}
/**
* @see BiometricPrompt.AuthenticationCallback#onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult)
*/
@Override
public void onAuthenticationSucceeded(final BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
mCallback.onAuthenticationSucceeded();
}
BiometricPromptApi28Impl(@NonNull Context context, @NonNull BiometricPrompt prompt) {
this.context = context;
this.biometricPrompt = prompt;
}
CryptoObjectApi28Impl(BiometricPrompt.CryptoObject cryptoObject) {
this.cryptoObject = cryptoObject;
}
@TargetApi(P)
@Deprecated
private void showBiometricPrompt(FragmentActivity activity, FingerprintDialogCallbacks callback, Cipher cipher) {
CancellationSignal mCancellationSignal = new CancellationSignal();
BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(activity)
.setTitle(activity.getString(R.string.fingerprint_alert_title))
.setNegativeButton(activity.getString(R.string.cancel), activity.getMainExecutor(), (dialogInterface, i) -> {
callback.onFingerprintCancel();
})
.build();
BiometricPrompt.AuthenticationCallback authenticationCallback = new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
callback.onFingerprintCancel();
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
super.onAuthenticationHelp(helpCode, helpString);
callback.onFingerprintCancel();
}
@Override
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
if (result.getCryptoObject() != null) {
callback.onFingerprintSuccess(result.getCryptoObject().getCipher());
} else {
callback.onFingerprintSuccess(null);
}
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
callback.onFingerprintCancel();
}
};
biometricPrompt.authenticate(mCancellationSignal, activity.getMainExecutor(), authenticationCallback);
}
@Override
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
biometricCallback.onAuthenticationSuccessful(result.getCryptoObject().getCipher());
}