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

Обнаружение события "домашняя кнопка нажата" в службе android, отображающей пользовательский интерфейс (аналогичный тембрам facebook)

В facebook chatheads, которые являются частью приложения facebook messenger, я заметил следующее поведение: Насколько я вижу, сам чат-голова и открытый экран чата являются частью службы. Нет активности.

Как я могу быть уверен? После того, как я вернусь домой на открывшемся экране чата, он будет сведен к минимуму обратно в чат-головку, и я сразу смогу снова открыть экран чата. Если экран чата был активным, то повторное открытие активности через startActivity(intent) после нажатия кнопки "домой" задерживало начало активности, как указано здесь: Запуск активности из службы после нажатия кнопки HOME без 5-секундной задержки

и здесь: Причина задержки 5 секунд для отображения активности при нажатии кнопки "домой" ?

в моем сервисе onCreate method, я использую следующий код для отображения пользовательского интерфейса из службы:

public class ServiceTest extends Service {
...
    @Override 
    public void onCreate() {
        super.onCreate();

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

        windowManager.addView(someView, params);
    }
....
}

Есть ли у кого-нибудь идея, как я могу получить событие "нажатие кнопки дома" непосредственно из службы, отображающей пользовательский интерфейс? Я хотел бы свести к минимуму мой взгляд (подобно головам чата facebook), когда пользователь нажимает кнопку "домой".

4b9b3361

Ответ 1

после моих собственных исследований по этому вопросу я пришел со следующими выводами:

Facebook "перехватывает" кнопки навигации, указав флаг TYPE_SYSTEM_OVERLAY. посмотрите этот пост, предоставленный @jawsware

делать то, что он советует не делать - приведет к "влиянию" на управление навигационными кнопками

используя этот флаг, фокусируется на вашем наложении и фокусируется на активности.

с обратным вызовом просмотра onFocusChangedListener или слушателем OnKey они реагируют на него с закрытием полноэкранного режима наложения.

что также объясняет, как они реагируют на него с помощью трех кнопок навигации - задач дома/назад/последних

Ответ 2

Вы можете добиться этого, переопределив View.onCloseSystemDialogs(). Вам может потребоваться проверить View.java, потому что этот метод не отображается в документе API.

Очевидно, что мы не можем обнаружить кнопку "Главная кнопка нажата" в целом. В большинстве случаев окно создается startActivity(). И процедура CloseSystemDialogs, вызванная нажатием кнопки "Главная", обрабатывается внутренним классом платформы Android, PhoneWindow.DecorView в качестве предка ViewRootImpl. Но когда мы напрямую добавляем представления в диспетчер окон, просмотр предка ViewRootImpl является нашим обычным представлением, но PhoneWindow.DecorView. Проверка исходного кода ViewRootImpl.java может быть проще понять.

KeyEvent.KEYCODE_APP_SWITCH также вызывает процедуру closeSystemDialogs. Это объясняет, как работают facebook chatheads.

Ответ 3

ok полное редактирование моего ответа,

Переопределите метод ниже в вашей деятельности.

 @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);           
    }

После переопределения вышеописанного метода теперь вы можете легко прослушать нажатие клавиши HOME в своей активности с помощью метода onKeyDown().

  @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {     

        if(keyCode == KeyEvent.KEYCODE_HOME)
        {
           //The Code Want to Perform. 
        }
    });

попробуйте эту надежду, это поможет

Ответ 4

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

ActivityManager am = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);
am.getRunningTasks(1).get(0).topActivity...

Ответ 5

Это мой путь. Он работает нормально. Поместите его в функцию onReceive().

if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
    {
        String reason = intent.getStringExtra(SYSTEM_REASON);

        //Toast.makeText(context,"ACTION_CLOSE_SYSTEM_DIALOGS : Reason : " + reason ,Toast.LENGTH_LONG).show();

        // Detect home screen key press or "recent app" key pressed when screen is in unlocked state
        if (reason != null)
        {
            if (reason.equals(SYSTEM_HOME_KEY))
            {
            // For Home press
            }
            else if (reason.equals(SYSTEM_RECENT_APPS))
            {
            // For long press
            }
        }
    }

Ответ 6

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

Простым и грубым способом сделать это было бы поддержание статического флага visible в вашем приложении singleton и изменение его из каждого вашего действия. В onPause() установите его в false, а в onResume() и onCreate() установите его в true.

Затем просто проверьте состояние этого флага и действуйте соответствующим образом. Если это правда, это означает, что ваше приложение видно.

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

Ответ 7

Вот пример рабочего кода.

mLinear =  new LinearLayout(getApplicationContext()) {

          //home or recent button
          public void onCloseSystemDialogs(String reason) {
              //The Code Want to Perform. 
          }

          @Override
          public boolean dispatchKeyEvent(KeyEvent event) {
              if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
                || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP
                || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN
                || event.getKeyCode() == KeyEvent.KEYCODE_CAMERA ) {

              //The Code Want to Perform.
              }
          return super.dispatchKeyEvent(event);
          }
};

mLinear.setFocusable(true);

View mView = inflate.inflate(R.layout.floating_panel_layout, mLinear);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);

//params
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
             width,
             height,
             WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
             WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
              PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
wm.addView(mView, params);

Ответ 8

Вы можете добавить категорию HOME в файл манифеста.