Подтвердить что ты не робот

Видимость строки состояния /TYPE _SYSTEM_OVERLAY не изменяется автоматически

Я использую известный метод TYPE_SYSTEM_OVERLAY для создания полноэкранного наложения, которое всегда поверх других представлений.

В a Moto Atrix2 API15 и для каждого AVD от API 10 до 17 вид наложения автоматически изменяется (расширяется вертикально), когда строка состояния скрыта другим приложением. Оверлей, похоже, "останется на вершине" всех других представлений, как мне кажется. Когда индикатор состояния снова отображается, наложение автоматически уменьшает его размер (меньше вертикальных пикселей, в основном вычитая высоту строки состояния).

Это желаемое поведение, и я склонен думать, что это не исключение или ошибочное поведение из-за его работы на многих разных эмуляторах, а также, по крайней мере, у одного производителя устройства (motorola), возможно, больше, но у меня нет доступ к addtl devices.

Проблема: В Samsung GS2 (API15), а также в тесте Kindle Fire (API10?) наложение не будет автоматически изменяться (заполнять пространство, в котором была строка состояния некогда), когда строка состояния скрыта другое приложение (строка состояния за полноэкранным приложением). На этих устройствах после создания представления в первый раз я не получаю больше событий от переопределения onSizeChanged для представления.

Вот соответствующий код:

params = new WindowManager.LayoutParams( 
    1, WindowManager.LayoutParams.MATCH_PARENT, 
    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 
    PixelFormat.TRANSPARENT);
wm.addView(sizeLayout, params);

sizeLayout имеет переопределение onSizeChanged.

Я играл со всеми windowmanager layoutparam, которые я могу найти, включая SYSTEM_ALERT, FLAG_LAYOUT_IN_SCREEN и т.д. Я не буду спать, пока не смогу это понять!

Редактировать 11/30/12: я нашел это из @deviant: qaru.site/info/143536/..., что в основном является тем, что я делаю, однако проблема остается на некоторых устройствах, не изменяя автоматически систему system_overlay. Возможно, я должен поднять ошибку.

Подробнее INFO: ЕСЛИ я заставляю перерисовать (или даже просто загружать приложение наложения), когда в верхней части дерева представлений есть приложение с полным экраном, мое наложение по-прежнему не нарисовывает пробел, который обычно занимает строка состояния (даже несмотря на то, что строка состояния не отображается во время рисования), поэтому кажется, что наложение не накладывается поверх верхнего окна, которое является полноэкранным (и я создал и протестировал многие полные приложения экрана, используя различные методы, чтобы заставить их работать в полноэкранном режиме). На этих устройствах единственный способ заставить оверлей рисовать поверх строки состояния (даже если строка состояния не отображается) заключается в использовании флага FLAG_LAYOUT_IN_SCREEN, но тогда размер макета никогда не изменяется, всегда заполнен экран и, следовательно, вернуться к исходной проблеме, почему это работает на некоторых устройствах, но не в других.

Редактировать 12/12/12. Поэтому мне больше не повезло, и я попытался использовать getLocalVisibleRect для просмотров, но, к сожалению, поскольку мое приложение не имеет собственных представлений SystemUI он не может определить, что ниже наложений. Я полагаю, что с помощью специального ПЗУ я мог бы это сделать, но мне нужно решение без root.

Я вижу, что другие приложения на рынке имеют ту же проблему, что и обнаружение строки состояния на неработающих телефонах, перечисленных выше. Пример: холодный инструмент, панель состояния omega и строка состояния+. Баунти поднялась.

Редактировать 12/19/12 Добавлены фотографии. Обратите внимание, что на рабочем устройстве серая область также "покрывает" черную область (любое приложение, которое в настоящее время полноэкранное), черная область фактически покрывает весь экран, я просто показываю серое пространство как мое наложение, хотя оно также полный экран (минус или плюс высота строки состояния в зависимости от рабочего/нерабочего устройства и независимо от того, находится ли он в поле зрения или нет).

enter image description hereenter image description here

4b9b3361

Ответ 1

Надеюсь, я понимаю, что вы здесь, но в моем приложении (TEAM BatteryBar) у меня была аналогичная проблема. (без минимальных разрешений root)

Я не смог обнаружить полный экран ни о чем ниже API11 (и прерывистый для некоторых (Samsung в основном) устройств выше API11). Поэтому я создал для него пользовательский прослушиватель, добавив второй макет в WindowManager с другим параметром макета, а затем переопределив onLayout, чтобы проверить, находится ли statusBar или нет, путем проверки размера окна. оттуда вы можете делать все, что вам нужно, до вашего основного вида.

Я собирался его убрать, но это сработало, поэтому я не сделал этого: P-код старше года и с того момента, когда я начал кодирование для Android, так что да. Пища для размышлений. надеюсь, что это поможет.

вот код в репо в моем github с копией, вставляемой прямо из моего приложения, о том, как я его использую. небольшой фрагмент здесь

wm.addView(sizeLayout, params);// add your view

// then add the next one
Screendetect mDetector;
mDetector = new Screendetect(this);
mDetector.setOnFullScreenListener(new OnFullScreenListener() {
            @Override
            public void fsChanged(boolean FS_Bool) {
                // TODO rethink this to be better.... bit hacky...
                if (FS_Bool) {
                    Log.d("battbardetect", "Statusbar hidden");
                    FS_vissible(); // do what ever you need to
                } else if (!FS_Bool) {
                    Log.d("battbardetect", "Statusbar Vissible"); 
                    FS_hidden(); // do what ever you need to
                }
            }
        });
wm.addView(mDetector, params);

Ответ 2

Я думаю, что это может быть одна и та же проблема с укрытием заголовка в диалоговых окнах, где система устанавливает видимость скрытым, а не ушла. Это вызывает неправильное центрирование диалогового окна.

Для этого, вот как я его исправляю. Это может сработать для вашей ситуации, но вам может потребоваться настроить его для имени идентификатора строки состояния.

Window window = dialog.getWindow();
View view = window.getDecorView();
int topPanelId = getResources().getIdentifier("topPanel", "id", "android");
LinearLayout topPanel = (LinearLayout) view.findViewById(topPanelId);
topPanel.setVisibility(View.GONE);