Immersive mode instructions reappear every time the device enters this mode

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-30 11:36:13

问题


My app uses the new "immersive mode" by calling (in onCreate):

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

This works great, but the "how-to" popup ("Swipe down from the top to exit full screen") appears every time the Activity is launched (if the phone is being locked while the activity was showing), even though the user has acknowledged the popup. As far as I understand, the popup is automatically generated by the system, so there's nothing I can do to change this situation, correct?

This issue is reproducible as follows:

  1. Launch immersive Activity [no popup appears, only on the very first launch (correctly)]
  2. Press the power button to switch off screen while the activity is showing
  3. Press power button again to switch on screen
  4. Close Activity by calling finish() e.g. from a button or menu option
  5. Launch Activity again - popup reappears

The popup does NOT reappear if the activity is launched, closed, and relaunched without hitting the power-button in between. Also, it ONLY reappears if the activity was topmost while the power button was pressed.

Correction: The Activity needs to be closed by calling "finish()" (e.g. from a button or a menu option). It works correctly if the Activity is closed by the back-key.

I've uploaded a sample app here: https://github.com/niko001/com.greatbytes.immersivebug/tree/master/Test5

EDIT: There's now an Xposed module to disable the "panic mode", so I guess I'm not alone in seeing this is an annoyance ;)


回答1:


Really interesting question! Thanks to your clear instructions, reproducing the issue wasn't a problem.

Alright, after digging through the source for almost 30-minutes and saying why would they do this? a bunch of times, I think I finally get it. I'll try to explain the best I can, but this is only my interpretation, and may not be correct:

Someone at android realized that the Immersive Mode will send people into a state of panic: how do i exit? (_sorry, I don't know what else the panic would be about_).

In this state of panic, the user will turn to the POWER BUTTON

.... > Power button --> User turns screen off (at x milliseconds since EPOCH)

.... > Praying that the navigation bar comes back

.... > Power button --> User turns screen on (at y milliseconds since EPOCH)

Now, the duration y - x is of significance. We'll discuss it a bit later, but first, let's look at how panic is defined:

panic happens when Praying the navigation bar comes back lasts less than 5 seconds. This value is held by:

mPanicThresholdMs = context.getResources()
                 .getInteger(R.integer.config_immersive_mode_confirmation_panic);

<!-- Threshold (in ms) under which a screen off / screen on will be considered 
     a reset of the immersive mode confirmation prompt.-->
<integer name="config_immersive_mode_confirmation_panic">5000</integer>

Ah, okay. So, it doesn't matter if the user has already acknowledged once, the prompt will be back if the above-mentioned criterion is met - even on the 100th launch.

And here's where the action happens:

public void onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) {
    if (mPanicPackage != null && !isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
        // turning the screen back on within the panic threshold
        unconfirmPackage(mPanicPackage);
    }
    if (isScreenOn && inImmersiveMode) {
        // turning the screen off, remember if we were in immersive mode
        mPanicTime = time;
        mPanicPackage = mLastPackage;
    } else {
        mPanicTime = 0;
        mPanicPackage = null;
    }
}

(time - mPanicTime < mPanicThresholdMs) ==> ( y - x ) < 5000

unconfirmPackage(mPanicPackage) removes mPanicPackage (yours) from the list of packages stored under Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS.

Needless to say, I find this strange... and wrong. Even if the user is in panic, and takes the power button route, s/he won't see the helpful reminder until next launch. So, what's the point?

Or may be, I am wrong about the definition of panic.

so there's nothing I can do to change this situation, correct?

Correct. To fix this, you would have to add your package-name to value held by Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS. But, to write to a secure setting, your app requires WRITE_SECURE_SETTINGS permission - not for use by third-party applications.

Links:

ImmersiveModeConfirmation (helper class that manages showing/hiding of confirmation prompt)




回答2:


More succinctly - in K, users will see the confirmation when entering immersive mode if:

  • They have not yet confirmed it for that app (package).
  • They "panicked" last time they were in immersive mode. "Panic" in this case means toggling the screen off, then back on in under 5 seconds (by default).


来源:https://stackoverflow.com/questions/20075041/immersive-mode-instructions-reappear-every-time-the-device-enters-this-mode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!