如何在UI线程上运行生物识别提示并合并回原始线程?



我正在尝试使用生物识别身份验证。然而,我的设置是复杂的,基本上我试图保持函数同步,因为它是从c++调用:

用户交互->c++函数>Java JNI函数->生物识别认证<-需要返回

跳过c++代码,通过JNI调用以下函数:

public String getSeed() throws ExecutionException, InterruptedException {
Context reactContext = this.getReactApplicationContext();
Activity act = this.getCurrentActivity();
act.runOnUiThread(new Runnable() {
@Override
public void run() {
Executor executor = ContextCompat.getMainExecutor(reactContext);
BiometricPrompt.AuthenticationCallback authenticationCallback = new WalletCoreAuthenticationCallback();
BiometricPrompt.PromptInfo info = BiometricUtils.createBiometricPromptInfo("ROPO", "ROPO", "ROPO");
BiometricPrompt prompt = new BiometricPrompt((FragmentActivity) act, executor, authenticationCallback);
prompt.authenticate(info);
}
});
// Here I need a Handler.merge or something similar to pause the execution while the user authenticates and then I retrieve the answer.
try {
return keyStore.getPlainText(getReactApplicationContext(), SEED_KEY);
} catch (FileNotFoundException fnfe) {
Log.w(Constants.TAG, "Could not get seed (file not found)");
return null;
} catch (Exception e) {
Log.w(Constants.TAG, "Could not get seed");
return null;
}
}

这个想法是:如果用户身份验证失败,我不获取敏感信息(keystore . get明文)。

然而,问题在于BiometricPrompt需要从主(UI)线程调用。我是一个Android新手,到目前为止,这是我能想到的最好的,它实际上提示用户进行身份验证,但我不知道如何暂停/加入主java函数调用,直到用户通过身份验证。

这可能吗?

我找到了一种简单的方法,使用互斥锁。

对父Java的每次调用都会创建一个互斥锁(我还向WalletCoreAuthenticationCallback对象添加了一个字段来保存响应)。然后我在调用中释放互斥锁,并检查存储的响应。

final Semaphore mutex = new Semaphore(0);
// This object now internally saves the response of the authentication callback
WalletCoreAuthenticationCallback authenticationCallback = new WalletCoreAuthenticationCallback(mutex);
act.runOnUiThread(new Runnable() {
@Override
public void run() {
Executor executor = ContextCompat.getMainExecutor(reactContext);
BiometricPrompt.PromptInfo info = BiometricUtils.createBiometricPromptInfo("ROPO", "ROPO", "ROPO");
BiometricPrompt prompt = new BiometricPrompt((FragmentActivity) act, executor, authenticationCallback);
prompt.authenticate(info);
}
});
try {
mutex.acquire();
} catch (InterruptedException e) {
Log.e(Constants.TAG, "INterruped mutex exception");
}
if(!authenticationCallback.isAuthenticated) {
return null;
}

然而,这有一个副作用,基本上锁定调用线程,我从一个React Native应用程序中调用这个,这基本上意味着它冻结了应用程序。然而,由于Auth是如此重要的一步,冻结应用程序是可以的,因为用户无论如何都不能在没有身份验证的情况下继续。

如果有人有更优雅的解决方案,很高兴去看看。

最新更新