Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to lock Android device after unlocking with setShowWhenLocked(true);

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?

like image 288
Mr. Robot Avatar asked Mar 26 '20 21:03

Mr. Robot


1 Answers

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.

like image 159
Lukas Makor Avatar answered Oct 28 '22 07:10

Lukas Makor