Search code examples
androidlockscreen

Android Lockscreen with FingerPrint support


I have an app that serves as custom lockscreen and I want to preserve unlock functionality using fingerprint. I want to unlock my phone when device screen is off or when I am looking at my lockscreen. The lockscreen is an activity that runs above all other components. If device is idle (screen is off) and I use fingerprint, phone turns on but my lockscreen is still visible. If I use fingerprint when my lockscreen is shown, nothing happens, the sensor is not active. If I implement listening for fingerprint with FingerprintManager by myself I am able to listen for successful fingerprint use, but if I dismiss my activity the lockscreen is still turned on.

I`ve been looking at Next by Microsoft and they somehow achieved that. My guess is that they do not run Activity as their lockscreen but they just draw their view into WindowManager and somehow listens for lockscreen unlock and then they hides their UI. Problem with this approach (I think at least) is that without Activity I cannot set Window flags for immersive mode and I cannot draw over status/navigation bar.


Solution

  • I`ve finally solved it. The key is to not listen for fingerprint myself but just let system handle it. My lockscreen is view that is added to WindowManager like this

    val params = WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
                        WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION or
                                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
                                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
                                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
                                WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
                                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                        , PixelFormat.TRANSLUCENT)
    
    manager.addView(lockscreenView, params)
    

    and lockscreen view in onViewAttached sets UI visibility flags

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
     }
    

    Then you have to provide your own custom unlock mechanism so user can dismiss your lockscreen and additionaly listen for Intent.ACTION_USER_PRESENT broadcast that indicates that lockscreen is unlocked (for example with fingerprint)