Question

I want to use Face Unlock as a second factor for my app, since most of my users will not lock their phones with a password.

Are there Android APIs available to integrate Face Unlock in an Android app?

There are Face Detection APIs out there for photo recognition, but I couldn't find APIs available that can be used in an offline scenario, specifically for an additional factor within an application.

If you need a real world example, assume that this is a password manager, or the phone will be loaned to a child... and the owner never locks the phone. Face unlock will secure the things they need private.

Was it helpful?

Solution

For those who don't feel like reading: OpenCV can accomplish all of what you are looking for in terms of facial recognition. (Documentation here)

This is a difficult question to answer as few existing android applications make use of the facial recognition technology you ask for. However, you may want to check these sites out:

A good list of face detection software

A decent walkthrough for some of the main api's available

Another higher quality tutorial...

Documentation for default android FaceDetector class

It might be useful to take a look at this sample which uses the OpenCV library

I understand the problem of not being able to accomplish this offline. To get around this you could always add a "backup" such as a normal passcode which only comes into effect after it is discovered that the user has no internet access. Another solution would be to simply require a stable internet/cellular connection for your app to function.

EDIT: Unfortunately,

Face unlock is closed-source google proprietary code, so we have no opportunity to modify it. Source: http://forum.xda-developers.com/showthread.php?t=1367610

You are probably looking for the following information:

The most popular library for image manipulate and the like seems to be OpenCV which has a Java wrapper that can be found here

You would also need this to be running in the background, periodically checking user's face without an indication that this is taking place so you should keep that in mind when choosing your library/approach

Source: A while ago, I implemented face recognition technology as a way for users to sign into one of my apps so I am just recounting what I remember in my search for an answer to this same question

Your scenario:

If you need a real world example, assume that this is a password manager, or the phone will be loaned to a child... and the owner never locks the phone. Face unlock will secure the things they need private.

As for accomplishing this, I would read up on android encryption if that is what you mean by "secure the things they need private." Otherwise if you just want to create an "app lock" of sorts using face recognition instead of a passcode, this is much more simply and can be accomplished using intents/basic if-statements, etc. (I'm assuming you are accomplished with Java)

Please feel free to ask questions. Currently I am looking for my old source code where I did something similar to what you want but I doubt I still have it...

UPDATE: Check this out... and yes OpenCV can be used offline so I think this is what you guys are looking for

OTHER TIPS

For now, you can use Biometric API which under the hood checks which type of biometric is available on the device (face unlock or fingerprint) and will do all the stuff, including handling many hardware-specific issues.

So, start with adding the dependency:

implementation 'androidx.biometric:biometric:1.0.1'

You can check availability with the following method:

val biometricManager = BiometricManager.from(this)
when (biometricManager.canAuthenticate()) {
    BiometricManager.BIOMETRIC_SUCCESS ->
       // App can authenticate using biometrics
    BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
       // No biometric features available on this device
    BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
       // Biometric features are currently unavailable
    BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED ->
       // The user hasn't associated any biometric credentials with their account
}

Use a provided for you system dialog:

private lateinit var executor: Executor
private lateinit var biometricPrompt: BiometricPrompt
private lateinit var promptInfo: BiometricPrompt.PromptInfo

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_login)
    executor = ContextCompat.getMainExecutor(this)
    biometricPrompt = BiometricPrompt(this, executor,
            object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationError(errorCode: Int,
                errString: CharSequence) {
            super.onAuthenticationError(errorCode, errString)
            // Authentication error
        }

        override fun onAuthenticationSucceeded(
                result: BiometricPrompt.AuthenticationResult) {
            super.onAuthenticationSucceeded(result)
            // Authentication succeeded!
        }

        override fun onAuthenticationFailed() {
            super.onAuthenticationFailed()
            // Authentication failed
        }
    })

    promptInfo = BiometricPrompt.PromptInfo.Builder()
            .setTitle("Biometric login for my app")
            .setSubtitle("Log in using your biometric credential")
            .setNegativeButtonText("Use account password")
            .build()

    // Prompt appears when user clicks "Log in".
    // Consider integrating with the keystore to unlock cryptographic operations,
    // if needed by your app.
    biometricLoginButton.setOnClickListener {
        biometricPrompt.authenticate(promptInfo)
    }
}

If you want your app to unlock press a confirmation after a face unlock (for instance, when user performs a purchase) - it is the default behavior. If you want to unlock the app right away without confirmation:

// Allows the user to authenticate without performing an action, such as pressing a button, after their biometric credential is accepted.

promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setNegativeButtonText("Use account password")
        .setConfirmationRequired(false)
        .build()

enter image description here

Also, you may need to set a fallback for user to unlock with the device pin/password/pattern. It is done in the following way:

promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        // Cannot call setNegativeButtonText() and
        // setDeviceCredentialAllowed() at the same time.
        // .setNegativeButtonText("Use account password")
        .setDeviceCredentialAllowed(true)
        .build()

Additional info and details on cryptography can be found here: https://developer.android.com/training/sign-in/biometric-auth

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top