I am creating a video calling app and have the following code which is called when the application receives a push notification – it unlocks the screen and presents an ‘incoming call’ user interface:
public class MainActivity extends ReactActivity { @Override protected String getMainComponentName() { return "x"; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { setShowWhenLocked(true); setTurnScreenOn(true); } getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); } }
This works fine when a call is incoming – the user can interact with the app using the UI presented. However, the problem is is that if the app is in the foreground and the phone is then locked, when the unlock button is pressed on the side of the phone, the app is displayed, instead of the keyguard / lock screen being displayed. It permanently allows access to the app if it is in the foreground and the phone is locked and the unlock button is pressed.
I want the app to appear when the it receives a push notification and the screen is locked, but I also want the user to be able to lock the device fully and not give the user access to the app after pressing the lock button.
How can I achieve this?
Advertisement
Answer
As far as I know the best solution to that problem is having multiple types of activities.
In the first activity (calling activity) you set setShowWhenLocked and setTurnScreenOn to true (like you did).
When a call comes in, you start the calling activity which handles the call, because you set the two attributes, the activitiy will be shown to the user even if the device is locked.
Furthermore, while the call activitiy is active, the user will be able to “lock” his device (i.e. press the power button), and when he unlocks he will be presented with the calling activity again (without entering the code).
This is the same behaviour as most default android calling/phone apps have.
The second activity is used for your other logic, that should only be accessible when the user really unlocks his phone. (i.e. enter the code)
So, when the phone call is ended, you start the second activity from the calling activity, e.g. like this:
Intent intent = new Intent(this, SecondActivity.class); this.startActivity(intent);
where this
is the instance of the calling activity
The just started SecondActivity
will then automatically be locked behind the lockscreen (i.e. not accessible without unlock) if the phone was locked before.
I just tested this behaviour in a small test project, if you need further assistance, just ask.