WindowManager.addView наложение (наложение) программной клавиши ИЛИ навигационная панель

Сегодня я видел приложение, которое перекрывает весь экран, включая навигационную панель (или софт-клавишу, которая возвращает назад, домой и т. Д.). это CF.Lumen(требуется Android 4.4+) от chainfire.

Я только что вспомнил, что это НЕ ВОЗМОЖНО при общем подходе, и многие ответы SO сказали мне. Поэтому я посмотрел вниз смайли коды от Lumens apk(извините цепной огонь), нашел 0x7d6 как спецификатор типа, который TYPE_SYSTEM_OVERLAY, В общем, это делает вид наложений поверх экрана блокировки. Выглядит хорошо, но не перекрывает область навигационной панели. даже на экране блокировки. Я сделал замену MATCH_PARENT в 9999 но это все еще не будет перекрывать область навигационной панели.

Я посмотрел вниз исходный код Android, нашел интересное, что имеет больше типов недокументированных.

FIRST_SYSTEM_WINDOW = 2000;

TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW + 19;

TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW + 21;

Я применил их к своему приложению, но получил сбой говорит, что разрешение отказано. Это требует INTERNAL_SYSTEM_WINDOW ИЛИ что-то более недокументированное, чем SYSTEM_ALERT_WINDOW, эти разрешения предоставляются только для системных приложений.

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

Что я должен сделать, чтобы сделать это?(Сделать оверлей, включая область навигационной панели)

final WindowManager.LayoutParams paramsRL = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
            PixelFormat.TRANSLUCENT);
windowManager.addView(view_floating, paramsRL);

1 ответ

Вот небольшой пример, который работает:

    FrameLayout frameLayout = new FrameLayout(context);
    frameLayout.setBackgroundColor(Color.BLACK);
    frameLayout.setAlpha(0.5f);

    windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                    | WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            PixelFormat.TRANSLUCENT);

    //make sure height includes the nav bar size (get the dimension of whole screen)
    params.height = screenHeight;
    params.width = screenWidth;
    windowManager.addView(frameLayout, params);

    //add your view to this frameLayout
    frameLayout.addView(....);

Вот три ключевые вещи:

  1. TYPE_SYSTEM_OVERLAY (или любые подобные типы), которые могут отображать контент на весь экран.

  2. FLAG_LAYOUT_NO_LIMITS, которая позволяет нам превышать допустимый размер.

  3. Установка дополнительной высоты должна быть закрыта за софт-клавишами. Основная проблема заключалась в том, что когда мы устанавливаем параметры в match_parent, он устанавливает высоту экрана минус навигационная панель, я полагаю. Установка дополнительной высоты решает проблему.

Не используйте WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, этот флаг заставит панель навигации всегда отображаться. Не знаю почему.

Другие вопросы по тегам