Search code examples
androidscreen-orientationdevice-orientation

How to prevent or handle onResume being called when phone screen is locked?


By default my app is set to orientation landscape. This is causing an issue when the device is locked because the orientation will change to portrait (to accommodate the locked screen) which in turn forces onResume to be called. When this happens all objects are null making the app vulnerable to crashes. I have made changes that prevent crashes and the app works 'ok'. OK meaning that when you return to the app from lock screen, for half a second the UI is in portrait orientation before snapping to the proper orientation.

Things I have done to resolve

i. Added null checks on all objects that would otherwise never be null in onResume

ii. Added android:configChanges="orientation|screenSize" in manifest

iii. Added android:screenOrientation="landscape" in manifest

What else can be done to make the transition from lock screen back into my app smoother, with no blips, blinks, or orientation changes?


Solution

  • As what I can understand from your problem. You facing null of all objects in onResume() which lead to the app crash. And you cannot really avoid onResume() being called again. It's expected behavior from activity lifecycle. But there's a trick. You can just create a flag to know if a screen was off/on in onPause(). Once the phone is unlock, it will call onResume() and you can manage that flag.

    boolean isScreenUnLock = false;        
    @Override
    protected void onPause() {
         super.onPause();
         PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
         isScreenUnLock = pm.isScreenOn();      
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        if(isScreenUnLock){
            //Do something
        }
    }
    

    But it seem not a better way. I would recommend to handle the activity state instead of avoid all objects in Activity null. Check this example for more detail.

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
      super.onSaveInstanceState(savedInstanceState);
      // Save UI state changes to the savedInstanceState.
      // This bundle will be passed to onCreate if the process is
      // killed and restarted.
      savedInstanceState.putBoolean("MyBoolean", true);
      savedInstanceState.putDouble("myDouble", 1.9);
      savedInstanceState.putInt("MyInt", 1);
      savedInstanceState.putString("MyString", "Welcome back to Android");
      // etc.
    }
    
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
      super.onRestoreInstanceState(savedInstanceState);
      // Restore UI state from the savedInstanceState.
      // This bundle has also been passed to onCreate.
      boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
      double myDouble = savedInstanceState.getDouble("myDouble");
      int myInt = savedInstanceState.getInt("MyInt");
      String myString = savedInstanceState.getString("MyString");
    }
    

    Or quick way to do handle state above. Just simple use this library.