Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/182.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 自定义生物特征提示_Android_Biometrics_Android 9.0 Pie_Android Fingerprint Api_Facial Identification - Fatal编程技术网

Android 自定义生物特征提示

Android 自定义生物特征提示,android,biometrics,android-9.0-pie,android-fingerprint-api,facial-identification,Android,Biometrics,Android 9.0 Pie,Android Fingerprint Api,Facial Identification,我对android设备中的自定义提示有问题。我只使用指纹授权,但一些安卓9.0(例如三星Galaxy S10+)授权设备在允许的情况下使用指纹,但面部身份验证也是如此。如果用户同时允许面部和指纹身份验证,则提示使用身份验证面部识别。我需要只允许指纹,如果用户不允许指纹,但面部是,我需要阻止它 文件告诉我这一点(来自) 。。。但是没有任何指导,我在源代码中找不到任何关于定制的内容 我的启动身份验证对话框的代码在这里 BiometricPrompt.Builder(context)

我对android设备中的自定义提示有问题。我只使用指纹授权,但一些安卓9.0(例如三星Galaxy S10+)授权设备在允许的情况下使用指纹,但面部身份验证也是如此。如果用户同时允许面部和指纹身份验证,则提示使用身份验证面部识别。我需要只允许指纹,如果用户不允许指纹,但面部是,我需要阻止它

文件告诉我这一点(来自)

。。。但是没有任何指导,我在源代码中找不到任何关于定制的内容

我的启动身份验证对话框的代码在这里

 BiometricPrompt.Builder(context)
                    .setTitle(biometricBuilder.title ?: "")
                    .setSubtitle(biometricBuilder.subtitle ?: "")
                    .setDescription(biometricBuilder.description ?: "")
                    .setNegativeButton(biometricBuilder.negativeButtonText ?: "",
                            context.mainExecutor, DialogInterface.OnClickListener { dialogInterface, i -> biometricCallback.onAuthenticationCancelled() })
                    .build()
                    .authenticate(CancellationSignal(), context.mainExecutor,
                            BiometricCallbackV28(biometricCallback))

感谢您提供的帮助

有点晚了,但我希望这个答案可以帮助其他开发人员。 我也在尝试实现同样的目标,最终得到了一个简单的解决方案:

调用
.authenticate()
时提供加密对象,如下所示:

/**
 * Prerequisites:
 * 1. Add
 * `implementation "androidx.biometric:biometric:1.0.1"` in build.gradle
 * 2. Add
 * `    <uses-permission android:name="android.permission.USE_BIOMETRIC" android:requiredFeature="false"/>`
 * in AndroidManifest.xml
 */
object BiometricHelper {
    private const val ENCRYPTION_BLOCK_MODE = KeyProperties.BLOCK_MODE_GCM
    private const val ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_NONE
    private const val ENCRYPTION_ALGORITHM = KeyProperties.KEY_ALGORITHM_AES
    private const val KEY_SIZE = 128

    private lateinit var biometricPrompt: BiometricPrompt

    fun authenticate(fragmentActivity: FragmentActivity, authCallback: BiometricPrompt.AuthenticationCallback){
        try {
            if (!fragmentActivity.supportFragmentManager.executePendingTransactions()) {
                biometricPrompt = createBiometricPrompt(fragmentActivity, authCallback)
                val promptInfo = createPromptInfo()
                biometricPrompt.authenticate(
                    promptInfo,
                    cryptoObject //Providing crypto object here will block Iris and Face Scan
                )
            }
        }
        catch (e: KeyPermanentlyInvalidatedException) {
            e.printStackTrace()
        }
        catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun createBiometricPrompt(fragmentActivity: FragmentActivity, authCallback: BiometricPrompt.AuthenticationCallback): BiometricPrompt {
        val executor = ContextCompat.getMainExecutor(fragmentActivity)
        return BiometricPrompt(fragmentActivity,  executor, authCallback)
    }

    private fun createPromptInfo(): BiometricPrompt.PromptInfo {
        return BiometricPrompt.PromptInfo.Builder()
            .setTitle("Authentication")
            .setConfirmationRequired(false)
            .setNegativeButtonText("Cancel")
            .setDeviceCredentialAllowed(false) //Don't Allow PIN/pattern/password authentication.
            .build()
    }
    //endregion


    //====================================================================================
    //region Dummy crypto object that is used just to block Face, Iris scan
    //====================================================================================
    /**
     * Crypto object requires STRONG biometric methods, and currently Android considers only
     * FingerPrint auth is STRONG enough. Therefore, providing a crypto object while calling
     * [androidx.biometric.BiometricPrompt.authenticate] will block Face and Iris Scan methods
     */
    private val cryptoObject by lazy {
        getDummyCryptoObject()
    }

    private fun getDummyCryptoObject(): BiometricPrompt.CryptoObject {
        val transformation = "$ENCRYPTION_ALGORITHM/$ENCRYPTION_BLOCK_MODE/$ENCRYPTION_PADDING"
        val cipher = Cipher.getInstance(transformation)
        var secKey = getOrCreateSecretKey(false)
        try {
            cipher.init(Cipher.ENCRYPT_MODE, secKey)
        }
        catch (e: KeyPermanentlyInvalidatedException) {
            e.printStackTrace()
            secKey = getOrCreateSecretKey(true)
            cipher.init(Cipher.ENCRYPT_MODE, secKey)
        }
        catch (e: Exception) {
            e.printStackTrace()
        }
        return BiometricPrompt.CryptoObject(cipher)
    }

    private fun getOrCreateSecretKey(mustCreateNew: Boolean): SecretKey {
        val keyStore = KeyStore.getInstance("AndroidKeyStore")
        keyStore.load(null)
        if (!mustCreateNew) {
            keyStore.getKey("dummyKey", null)?.let { return it as SecretKey }
        }

        val paramsBuilder = KeyGenParameterSpec.Builder("dummyKey",
            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
        paramsBuilder.apply {
            setBlockModes(ENCRYPTION_BLOCK_MODE)
            setEncryptionPaddings(ENCRYPTION_PADDING)
            setKeySize(KEY_SIZE)
            setUserAuthenticationRequired(true)
        }

        val keyGenParams = paramsBuilder.build()
        val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
            "AndroidKeyStore")
        keyGenerator.init(keyGenParams)
        return keyGenerator.generateKey()
    }
    //endregion
}
/**
*先决条件:
* 1. 添加
*`implementation“androidx.biometric:biometric:1.0.1”`in build.gradle
* 2. 添加
* `    `
*在AndroidManifest.xml中
*/
对象生物特征辅助程序{
private const val ENCRYPTION\u BLOCK\u MODE=KeyProperties.BLOCK\u MODE\u GCM
private const val ENCRYPTION_PADDING=KeyProperties.ENCRYPTION_PADDING_NONE
private const val ENCRYPTION_ALGORITHM=KeyProperties.KEY_ALGORITHM_AES
私有const val KEY_SIZE=128
私有lateinit var生物特征提示:生物特征提示
有趣的身份验证(fragmentActivity:fragmentActivity,authCallback:BiometricPrompt.AuthenticationCallback){
试一试{
如果(!fragmentActivity.supportFragmentManager.executePendingTransactions()){
biometricPrompt=CreateBometricPrompt(fragmentActivity,authCallback)
val promptInfo=createPromptInfo()
身份验证(
PrompInfo,
cryptoObject//此处提供cryptoObject将阻止虹膜和面部扫描
)
}
}
捕获(e:KeyPermanentlyInvalidateException){
e、 printStackTrace()
}
捕获(e:例外){
e、 printStackTrace()
}
}
private fun createBiometricPrompt(fragmentActivity:fragmentActivity,authCallback:BiometricPrompt.AuthenticationCallback):BiometricPrompt{
val executor=ContextCompat.getMainExecutor(碎片活动)
返回提示(fragmentActivity、executor、authCallback)
}
private fun createPromptInfo():BiometricPrompt.PromptInfo{
返回prompt.PromptInfo.Builder()
.setTitle(“认证”)
.setConfirmationRequired(错误)
.setNegativeButtonText(“取消”)
.setDeviceCredentialAllowed(false)//不允许PIN/模式/密码身份验证。
.build()
}
//端区
//====================================================================================
//区域虚拟加密对象,仅用于阻止人脸、虹膜扫描
//====================================================================================
/**
*加密对象需要强大的生物识别方法,目前Android只考虑
*指纹身份验证足够强大。因此,在调用
*[androidx.biometric.biometric Prompt.authenticate]将阻止人脸和虹膜扫描方法
*/
lazy的私有val加密对象{
getDummyCryptoObject()
}
private fun getDummyCryptoObject():BiometricPrompt.CryptoObject{
val transformation=“$ENCRYPTION\u ALGORITHM/$ENCRYPTION\u BLOCK\u MODE/$ENCRYPTION\u PADDING”
val cipher=cipher.getInstance(转换)
var secKey=getOrCreateSecretKey(false)
试一试{
cipher.init(cipher.ENCRYPT_模式,secKey)
}
捕获(e:KeyPermanentlyInvalidateException){
e、 printStackTrace()
secKey=getOrCreateSecretKey(真)
cipher.init(cipher.ENCRYPT_模式,secKey)
}
捕获(e:例外){
e、 printStackTrace()
}
返回提示。加密对象(密码)
}
private fun getOrCreateSecretKey(mustCreateNew:Boolean):SecretKey{
val keyStore=keyStore.getInstance(“AndroidKeyStore”)
keyStore.load(null)
如果(!mustCreateNew){
getKey(“dummyKey”,null)?。让{作为SecretKey返回它}
}
val paramsBuilder=KeyGenParameterSpec.Builder(“dummyKey”,
KeyProperties.PURPOSE\u加密或KeyProperties.PURPOSE\u解密)
paramsBuilder.apply{
设置锁定模式(加密块模式)
设置加密填充(加密填充)
设置键大小(键大小)
setUserAuthenticationRequired(true)
}
val keyGenParams=paramsBuilder.build()
val keyGenerator=keyGenerator.getInstance(KeyProperties.KEY\u算法),
“AndroidKeyStore”)
keyGenerator.init(keyGenParams)
return keyGenerator.generateKey()
}
//端区
}

编辑:
只有当该设备上的面部扫描和/或虹膜扫描验证被视为弱方法时,此解决方案才有效。

不幸的是,这不受支持。您所参考的文档仅供设备制造商使用,而非应用程序开发人员使用。它所说的是,最终用户应该能够在设置应用程序中手动选择他们首选的生物特征。因此,当我只需要指纹时,无法使用生物特征提示?目前不行。我在去年提到过这一点,但还没有收到任何有意义的回复。您对此问题有一些解决方案(首选一种身份验证和第二种阻止),或者同时使用两种方法(指纹和面部),目前使用
生物识别提示时没有解决方案。如果只允许使用指纹,可以使用
FingerprintManager
(不推荐使用)