我正在实现下面的本机 Android 代码来调用生物识别身份验证,并使用设备引脚/图案/密码作为备份。我在 android studio 中使用了以下代码,它适用于模拟器和物理设备。本质上,当应用程序启动以及按下按钮时会出现提示。
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.biometric.BiometricPrompt;
import androidx.core.content.ContextCompat;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
import java.util.concurrent.Executor;
public class MainActivity extends AppCompatActivity {
private Executor executor;
private BiometricPrompt biometricPrompt;
private BiometricPrompt.PromptInfo promptInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
executor = ContextCompat.getMainExecutor(this);
biometricPrompt = new BiometricPrompt(MainActivity.this,
executor, new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode,
@NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
Toast.makeText(getApplicationContext(),
"Authentication error: " + errString, Toast.LENGTH_SHORT)
.show();
}
@Override
public void onAuthenticationSucceeded(
@NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
Toast.makeText(getApplicationContext(),
"Authentication succeeded!", Toast.LENGTH_SHORT).show();
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
Toast.makeText(getApplicationContext(), "Authentication failed",
Toast.LENGTH_SHORT)
.show();
}
});
promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("Biometric login for my app")
.setSubtitle("Log in using your biometric credential")
.setAllowedAuthenticators(androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK | androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG | androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL)
.build();
biometricPrompt.authenticate(promptInfo);
// Prompt appears when user clicks "Log in".
// Consider integrating with the keystore to unlock cryptographic operations,
// if needed by your app.
Button biometricLoginButton = findViewById(R.id.b_launchAuth);
biometricLoginButton.setOnClickListener(view -> {
Log.d("b_launchAuth", "Pressed - Enter");
biometricPrompt.authenticate(promptInfo);
Log.d("b_launchAuth", "Pressed - Exit");
});
}
}
上面的代码需要添加构建提示: - "android.gradleDep=implementation("androidx.biometric:biometric:1.1.0")"
上面的代码引用了“this”(作为上下文:)和MainActivity.this(作为活动:)。我已导入 com.codename1.impl.android.AndroidNativeUtil 并尝试用 AndroidNativeUtil.getContext() 替换“this”,用 AndroidNativeUtil.getActivity() 替换“MainActivity.this”,但是我无法成功构建。
如果我注释掉除:-
之外的所有内容executor = ContextCompat.getMainExecutor(AndroidNativeUtil.getActivity());
或
executor = ContextCompat.getMainExecutor(AndroidNativeUtil.getContext());
然后我就可以成功构建了。我的问题似乎与 MainActivity.this 相关。
我当前的 cn1 MyNativeImpl.java 代码如下:-
package com.jamesco.maventestnew;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.biometric.BiometricPrompt;
import androidx.core.content.ContextCompat;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import java.util.concurrent.Executor;
import com.codename1.impl.android.AndroidNativeUtil;
public class MyNativeImpl {
private Executor executor;
private BiometricPrompt biometricPrompt;
private BiometricPrompt.PromptInfo promptInfo;
public boolean isSupported() {
return true;
}
public boolean nativeAuth(){
boolean AuthOK = false;
executor = ContextCompat.getMainExecutor(AndroidNativeUtil.getContext());
biometricPrompt = new BiometricPrompt(AndroidNativeUtil.getActivity(),
executor, new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode,
@NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
//Do nothing for now
}
@Override
public void onAuthenticationSucceeded(
@NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
AuthOK = true;
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
}
});
promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("Biometric login for my app")
.setSubtitle("Log in using your biometric credential")
.setAllowedAuthenticators(androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK | androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG | androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL)
.build();
biometricPrompt.authenticate(promptInfo);
return AuthOK;
}
}
这里是按要求指向错误日志的链接
您在聊天中发送的日志的错误是:
MyNativeImpl.java:78: error: no suitable constructor found for BiometricPrompt(Activity,Executor,<anonymous AuthenticationCallback>)
biometricPrompt = new BiometricPrompt(AndroidNativeUtil.getActivity(),
^
constructor BiometricPrompt.BiometricPrompt(FragmentActivity,Executor,AuthenticationCallback) is not applicable
(argument mismatch; Activity cannot be converted to FragmentActivity)
constructor BiometricPrompt.BiometricPrompt(Fragment,Executor,AuthenticationCallback) is not applicable
(argument mismatch; Activity cannot be converted to Fragment)
问题是生物识别代码假定为
Fragment
或FragmentActivity
。
我过去没有使用过片段,所以我只是在这里猜测,但我认为这样的事情可能会解决这个特定问题:
public class BiometricFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
// write the biometric code here...
}
}
您可以使用此未经测试的代码从本机代码启动它......:
BiometricFragment biometricFragment = new BiometricFragment();
getFragmentManager().beginTransaction()
.add(biometricFragment, "biometric_fragment")
.commit();