在android服务中检测'home button pressed'事件,显示一个UI(类似于facebook chatheads)

时间:2013-08-07 12:13:55

标签: android user-interface service

在facebook chatheads中,这是facebook messenger应用程序的一部分,我注意到以下行为: 据我所知,聊天头本身和打开的聊天屏幕都是服务的一部分。不涉及任何活动。

我怎么能确定? 在我打开的聊天屏幕上按回家后,它被最小化回聊天头,我可以立即重新打开聊天屏幕。如果聊天屏幕是活动,则在按下主页按钮后通过startActivity(intent)重新打开活动将延迟活动的开始,如下所示: Starting an activity from a service after HOME button pressed without the 5 seconds delay

在这里:Reason for 5 sec delay to show an activity on pressing the home button?

在我的服务onCreate方法中,我使用以下代码显示来自服务的UI:

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聊天头)。

8 个答案:

答案 0 :(得分:10)

在对这个问题进行自己的研究之后,我得出了以下结论:

Facebook通过提供标记TYPE_SYSTEM_OVERLAY属性“拦截”导航按钮。查看@jawsware提供的this post答案

做他不建议的事情 - 将导致控制导航按钮的“影响”

使用此标记可以关注叠加层,并从后面的活动中获得焦点。

使用onFocusChangedListener视图回调或OnKey listener他们通过关闭叠加层的全屏模式对其做出反应。

这也解释了他们如何通过3个导航按钮对其做出反应 - 主页/后退/最近的任务

答案 1 :(得分:4)

您可以通过覆盖View.onCloseSystemDialogs()来实现它。您可能需要检查View.java,因为此方法在API doc中不可见。

显然,我们一般都无法检测到“按下主页按钮”。在大多数情况下,窗口由startActivity()创建。由“Home button button”引起的CloseSystemDialogs例程由内部类的android框架PhoneWindow.DecorView处理,作为ViewRootImpl的视图祖先。但是当我们直接向窗口管理器添加视图时,查看ViewRootImpl的祖先是我们的自定义视图,而不是PhoneWindow.DecorView。检查ViewRootImpl.java的源代码可能更容易理解。

KeyEvent.KEYCODE_APP_SWITCH也会导致closeSystemDialogs例程。这解释了facebook聊天的工作原理。

答案 2 :(得分:2)

确定我的答案完整编辑,

在您的活动中覆盖以下方法。

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

覆盖上述方法后,现在您可以使用onKeyDown()方法轻松收听活动中的HOME键。

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

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

试试希望它有所帮助

答案 3 :(得分:2)

您可以监控(例如每200毫秒检查一次)最常运行的活动,看看它是您的活动还是其他活动,并知道它何时发生变化。 这也可以让你处理来电等情况。

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

答案 4 :(得分:2)

这是我的方式。它工作正常。把它放在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
            }
        }
    }

答案 5 :(得分:1)

我很确定facebook不会听主页按键,因为他们的逻辑要求聊天头出现,无论应用程序是什么,只要它不是facebook。

执行此操作的一种简单粗暴的方法是在应用程序单例中维护静态标志visible,并从您拥有的每个Activity中修改它。在onPause()中,将其设置为false,在onResume()和onCreate()中将其设置为true

然后只需检查此标志的状态,并采取相应措施。如果是真的,则表示您的应用可见。

您可能希望在对其执行操作之前添加一个小暂停,以防止每次更改活动时注入的视图都会闪烁。

答案 6 :(得分:1)

以下是工作示例代码。

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

答案 7 :(得分:0)

您可以将类别HOME添加到清单文件中。