Sebi
Sebi

Reputation: 145

How can i redirect my app to a lock screen when reenter app

My App could be locked with pin or fingerprint. I was able to do this on App Start with an "Start Up" Activity handle the pin/fingerprint stuff. But when it is once handled it is unlocked. But I want that when app was in background the lock screen is shown when the app is resumed. How can i manage this?

I was trying to start an intent when OnResume() of MainActivity is called.

@Override
protected void onResume() {
    super.onResume();

    Intent settingsIntent = new Intent(this, StartUpActivity.class);
    startActivity(settingsIntent);

}

But then it goes to an infinity loop ... :(. And with the resume I can not distinguish whether i came from another activity in my app or if the app was getting back in foreground.

I was also searching a bit but i didn't find a solution to this problem. If i was missed a solution, please provide a link.

Thanks, Sebi

Upvotes: 0

Views: 2864

Answers (3)

Pavlo Ostasha
Pavlo Ostasha

Reputation: 16719

It depends of how you've done your pin locking.

From the question I assume you've used some library or self made approach for that. In this case you may store some value isLocked in SharedPreferences and change it every time in onDestroy or in onStop to true. When user enters your app you should check if isLocked == true and prompt pin screen and change it to false on successful unlock, and if isLocked == false you can proceed with you app flow. If you want this to do it easier way - you may just have some static variable and manipulate its value - but on the app process recreation it will be changed to default value.

But I would recommend you to look into these methods - they are default for the Android OS.

With KeyguardManager you should use Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(title, description) in conjunction with startActivityForResult(intent) which will handle all the stuff you need and in onActivityResult you can handle moving forward.

Starting from API 28 you can use BiometricPrompt. You can use its Builder's method setDeviceCredentialAllowed(true) that will handle the pin stuff in similar way as KeyguardManager only with face/fingerprint options. BiometricPrompt has method authenticate that will actually prompt pin screen. It receives listener as argument so you won't need onActivityResult.

Upvotes: 0

Sebi
Sebi

Reputation: 145

I was able to do the check described in this answer: How to detect when an Android app goes to the background and come back to the foreground

With this I could check if the app came from the background or from an internal activity. And then I could call the Intent to my Start Up Activity.

Upvotes: 0

eleven
eleven

Reputation: 6857

onResume is a proper place to start. But you need to add also something which handles lock/unlock logic and define non-lockable screens to avoid loops.

Lock/unlock logic could be placed into something like PinManager

interface PinManager {

  /**
   * it's up to you how to define logic inside.
   * It could be locked after some time 
   * or locked when app is destroyed and removed from memory
   */
  fun isLocked():Boolean

  fun unlock(pin:List<Integer>)

  fun clear()
}

To avoid loops you can define interface:

interface NonLockedActivity {

}

And use it with actvity which verifies pin:

class VerifiyPinActivity: BaseActivity(), NonLockedActivity {
  fun verifiy(pin:List<Int>){

    if(pinManager.unlock(pin)){
      finish()//and show previous activity
    } else {
      //show invalid pin message
    } 
  }
}

and in base activities onResume could look like this

class BaseActivity: Activity(){
  fun onResume(){

    if(pinManager.isLocked()){
      navigator.verifyPin(this)
    }

  }
}

And hide implementation of opening activity in navigator:

class Navigator {
  fun verifyPin(acitvity:Activity) {
    if(activity is not NonLockedActivity) {
      startActivity(VerifiyPinActivity::class)
    }
  }
}

Upvotes: 1

Related Questions