Инструкции по погружающему режиму появляются каждый раз, когда устройство переходит в этот режим

Мое приложение использует новый "режим погружения", вызывая (в onCreate):

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

Это отлично работает, но всплывающее окно "how-to" ( "Прокрутка вниз сверху вниз для выхода из полноэкранного режима" ) появляется при каждом запуске Activity (если телефон блокируется во время показа активности), даже хотя пользователь подтвердил всплывающее окно. Насколько я понимаю, всплывающее окно автоматически генерируется системой, поэтому я ничего не могу сделать, чтобы изменить эту ситуацию, правильно?

Эта проблема воспроизводится следующим образом:

  • Запуск immersive Activity [всплывающее окно не появляется, только при первом запуске (правильно)]
  • Нажмите кнопку питания, чтобы отключить экран во время показа активности.
  • Нажмите кнопку питания еще раз, чтобы включить экран
  • Закрыть операцию, вызвав финиш(), например. с помощью кнопки или меню
  • Запустить активность снова - всплывающее окно снова появляется

Всплывающее окно НЕ появляется, если активность запущена, закрыта и перезапущена без нажатия кнопки включения питания. Кроме того, он ТОЛЬКО появляется, если активность была максимальной при нажатии кнопки питания.

Коррекция: действие нужно закрыть, вызвав "finish()" (например, с помощью кнопки или опции меню). Он работает правильно, если активность закрыта с помощью клавиши "Назад".

Я загрузил пример приложения здесь: https://github.com/niko001/com.greatbytes.immersivebug/tree/master/Test5

EDIT: теперь модуль Xposed отключает "режим паники", поэтому, я думаю, я не только в том, что это раздражает;)

Ответ 1

Действительно интересный вопрос! Благодаря вашим четким инструкциям воспроизведение этой проблемы не было проблемой.

Хорошо, после того, как вы пробрались через источник почти на 30 минут и сказал why would they do this? кучу раз, я думаю, что, наконец, понял. Я попытаюсь объяснить все, что могу, но это только моя интерпретация и может быть неправильной:

Кто-то из android понял, что Immersive Mode отправит людей в состояние паники: how do i exit? (_sorry, I don't know what else the panic would be about_).

В этом состоянии паники пользователь переключится на КНОПКУ POWER

.... > Кнопка питания → Пользователь отключает экран (при x миллисекундах с EPOCH)

.... > Молясь о возвращении навигационной панели

.... > Кнопка питания → Пользователь включает экран (при y миллисекундах с EPOCH)

Теперь значение y - x имеет значение. Мы обсудим это чуть позже, но сначала рассмотрим, как panic определено:

panic происходит, когда Praying the navigation bar comes back длится менее 5 секунд. Это значение сохраняется:

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>

А, ладно. Таким образом, не имеет значения, если пользователь уже подтвердил один раз, запрос вернется, если вышеупомянутый критерий будет выполнен - ​​даже на 100-м запуске.

И здесь, где происходит действие:

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;
    }
}

(время - mPanicTime < mPanicThresholdMs) == > (y - x) < 5000

unconfirmPackage(mPanicPackage) удаляет mPanicPackage (ваш) из списка пакетов, хранящихся в Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS.

Излишне говорить, что я нахожу это странным... и неправильным. Даже если пользователь находится в панике и берет маршрут кнопки питания, он/она не увидит полезного напоминания до следующего запуска. Итак, какой смысл?

Или может быть, я ошибаюсь в определении паники.

так что я ничего не могу сделать, чтобы изменить эту ситуацию, правильно?

Правильно. Чтобы исправить это, вам нужно добавить свое имя пакета в значение, удерживаемое Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS. Но для записи в безопасную настройку вашему приложению требуется разрешение WRITE_SECURE_SETTINGS - не для использования сторонними приложениями.

Ссылки:

ImmersiveModeConfirmation (вспомогательный класс, который управляет отображением/скрытием запроса подтверждения)

Ответ 2

Более кратко - в K пользователи будут видеть подтверждение при входе в режим погружения, если:

  • Они еще не подтвердили это приложение (пакет).
  • Они "запаниковали" в последний раз, когда они были в режиме погружения. "Паника" в этом случае означает выключить экран, а затем снова включить менее чем за 5 секунд (по умолчанию).