Reputation: 145
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
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
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
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