0

I'm writing an app that requires an access code when starting the app. I also request this access code when retrieving the app from the background. To do that I use the event "onResume". Unfortunately "onResume" is also triggered when I rotate the screen. But I do not want to miss the rotation of the screen.

I followed the solution from Martin Marconcini: How to detect when an Android app goes to the background and come back to the foreground. But this did not help because "onMoveToBackground" also gets triggered on screen rotation.

I tried saving the orientation in onSaveInstanceState and load it in onRestoreInstanceState. Now if the Orientation not changed i locked the app. If the orientation changed i disabled lock. Now the problem is, that when the app is locked, you only have to rotate the screen and the lock is gone.

Update 1: These are snippets from my mainactivity:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_check_passcode);
    initializeStartData();
    if (appStorage.getSetting(AppStorage.SETTING_PASSCODE)) {
        appUnlocked = false;
        loadPage(LAYOUT_ID_CHECK_PASSCODE); //which contains setContentView(R.layout.activity_check_passcode);
    } else {
        appUnlocked = true;
        loadPage(LAYOUT_ID_OVERVIEW); //which contains setContentView(R.layout.activity_overview);
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putInt(OUTSTATE_LAYOUT_ID, layoutId);
    outState.putInt(OUTSTATE_ORIENTATION, getResources().getConfiguration().orientation);
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if (savedInstanceState.getInt(OUTSTATE_ORIENTATION) != getResources().getConfiguration().orientation) {
        rotated = true;
    } else {
        rotated = false;
    }
    layoutId = savedInstanceState.getInt(OUTSTATE_LAYOUT_ID);
    loadPage(layoutId);
    }
}

@Override
protected void onResume() {
    super.onResume();
    if (appStorage.getSetting(AppStorage.SETTING_PASSCODE) && !rotated) {
        loadPage(LAYOUT_ID_CHECK_PASSCODE);
    }
    rotated = false;
}

As i said above, this code is nearly doing what i want:

  • Starting the app shows the passcode page.
  • Get the app back in the foreground (for example after pressing the home button) shows the passcode page.
  • Rotating the screen with app in foreground does no show the passcode page

The Problem:

  1. App is in foreground, screen orientation is portrait
  2. Put app in background by switching the app or pressing the home-button
  3. Rotate the screen (smartphone) to landscape
  4. Get the app back in the foreground (Will not show the passcode page because the rotation changed)

Update 2: (The Solution)

As described here: Solution I found the solution. This is my working code:

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(OUTSTATE_LOCKED, appUnlocked);
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    appUnlocked = savedInstanceState.getBoolean(OUTSTATE_LOCKED);
}

@Override
protected void onStop() {
    super.onStop();
    if (isChangingConfigurations()) {
        Toast.makeText(this, "Only screen rotation", Toast.LENGTH_SHORT).show();
    } else {
        setLocked();
        Toast.makeText(this, "Closed app, Locking", Toast.LENGTH_SHORT).show();
    }
}

@Override
protected void onResume() {
    super.onResume();
    if (appStorage.getSetting(AppStorage.SETTING_PASSCODE) && !appUnlocked) {
            passcodeUnlock = "";
            loadPage(LAYOUT_ID_CHECK_PASSCODE);
    }
}
  • The way you should aproach this is indeed using onSavInstanceState, if you're facing a issue like you said, its more likely that your code hava a flaw. Can you show you code so we can help you better? – Shermano Sep 02 '19 at 17:18
  • why are you storing the currentrly orientation on saveInstance bundle? Isn't more simple to save a boolean that represents the state of already unlocked or not? – Shermano Sep 02 '19 at 18:21
  • But how can i get the app to show the lock when coming back to the foreground? I would have to activate the lock at some point. When I start the app, I set the boolean in onCreate, but that will not be triggered in this case. Is the problem understandable? – Hunte060708 Sep 02 '19 at 19:01
  • Isn't the case to activate the lock in onPause() method? – Shermano Sep 02 '19 at 19:06
  • if I activate the lock in "onPause ()", the app is locked even with rotation. Because the rotation uses the same methods as clicking the Home button (onPause, onResume ...) – Hunte060708 Sep 03 '19 at 06:23

2 Answers2

0

There are two options that come to mind.

1) you can disable rotation, if it is not absolutely necessary.

2) you can store the current lock state before the rotation (save instance state, as you say) and restore it once the rotation is done. Based on the current state, you either display the lock or not.

peshkira
  • 6,069
  • 1
  • 33
  • 46
  • 1
    1. Disable rotation is not an option, my app is designed for smartphones and tablets and should work in landscape mode for this reason 2. I updated my question, I think it's like you suggested. I added the resulting problem of bypass the lock with rotation – Hunte060708 Sep 02 '19 at 18:00
  • 1
    go for number 2 it saves your UI data or use some proper architecture like MVVM which work independently of screen orientation changes – Pemba Tamang Sep 02 '19 at 18:04
0

I have found the solution in another question.

The trick is in "onStop ()" to check if a configuration change is made (for example, for a screen rotation). In order to check this, starting with API level 11+, the method "isChangingConfigurations ()" can be used.

I have implemented and tested the solution. It works :)

Here is the source of the solution: https://stackoverflow.com/a/28854326/7261695