CoDe
CoDe

Reputation: 11156

How to identify if device has in-display Biometric fingerprint support?

I'm writing a application feature to authenticate user using Biometric fingerprint authentication API. And it worked as expected with combination of BiometricPrompt API.

In general it display own UI dialog so it can be unified across Android device.(Improvement from Fingerprint Manager API)

In one of device testing scenario I come across in-display(on screen, e.g. Oneplus 6T device) fingerprint support instead rear biometric hardware option.

When I run application on it, on call of biometricPrompt.authenticate(..) instead of dialog it display in-display fingerprint authentication option. Which is ok, and manage by internal API of BiometricPrompt.

But it create some inconsistency to manage for developer.

  1. When it provide in-build authentication dialog, all fallback error displayed in dialog itself.
  2. But in case of in-display authentication I didn't found a way where it manage to display error message it-self. And I have to handle this fallback and display in a custom way.

Now question is

  1. Is there a way to manage/display message by in-display authentication view component.
  2. How can identify if device is support in-device biometric authentication.

Edit: Code reference I'm using:

import android.content.Context
import androidx.biometric.BiometricPrompt
import androidx.fragment.app.FragmentActivity
import java.lang.Exception
import java.util.concurrent.Executors
import javax.crypto.Cipher

class BiometricAuthenticationManager(private val context: Context) :
        BiometricPrompt.AuthenticationCallback() {

    private var biometricPrompt: BiometricPrompt? = null

    override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
        super.onAuthenticationError(errorCode, errString)
        biometricPrompt?.cancelAuthentication()
    }

    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
        super.onAuthenticationSucceeded(result)

    }

    override fun onAuthenticationFailed() {
        super.onAuthenticationFailed()
    }

    fun init(cipher: Cipher, promptInfo: BiometricPrompt.PromptInfo) {
        if (context is FragmentActivity) {
            val executor = Executors.newSingleThreadExecutor()

            biometricPrompt = BiometricPrompt(context, executor, this)
            biometricPrompt?.authenticate(promptInfo, BiometricPrompt.CryptoObject(cipher))
        } else {
            throw Exception(
                    "Check for FragmentActivity context.")
        }
    }
}

For further reference about how it look like, please find following attachment.

enter image description here

I try to check same scenario for lock screen, where I guess it uses custom implementation using FingerPrintManager class and display message.

enter image description here

Upvotes: 29

Views: 3163

Answers (2)

Serhii.Komlach
Serhii.Komlach

Reputation: 160

Faced with the same problem some time ago - OnePlus 6T has no Biometric UI, at the same time Samsung A51 - has its own (custom) UI for Fingerprint API and another for BiometricPrompt API. I tried to watch for Activity window focus loss (For OnePlus - activity do not lose focus, at the same time BiometricPrompt UI leads to focus loss), but appear a problem with the Samsung device.

The only solution that I found, and it works for now:

  1. Need to get the correct device name (for OnePlus for example, it should be not ONEPLUS A6003, but One Plus 6 instead)
  2. Need to perform request to https://m.gsmarena.com/res.php3?sSearch=Device+Name, you should get the list with matches, usually, first one is needed
  3. Parse HTML (from previews step) to get the link for device specification (like https://m.gsmarena.com/oneplus_6t-9350.php)
  4. Now you need to perform a request to this link and again parse HTML and get the "Sensors" section. You should get a string like "Fingerprint (under display, optical), accelerometer, gyro, proximity, compass"
  5. Split this string to get the list with sensors
  6. Now when you need to check if an in-display scanner is present on the device, just check for "fingerprint" and "under display" for the same sensor.

Link with impl. that can be used as an example

Upvotes: 1

Vijay S
Vijay S

Reputation: 418

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    //Fingerprint API only available on from Android 6.0 (M)
    FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
    if (!fingerprintManager.isHardwareDetected()) { 
        // Device doesn't support fingerprint authentication     
    } else if (!fingerprintManager.hasEnrolledFingerprints()) { 
        // User hasn't enrolled any fingerprints to authenticate with 
    } else { 
        // Everything is ready for fingerprint authentication 
    }
}

Dont Forget to Add

<uses-permission android:name=" android.permission.USE_BIOMETRIC" />

Upvotes: -1

Related Questions