在一个具有窗口的服务中检测导航按钮的触摸事件

9
我正在制作一款应用程序,该应用程序会在某些事件触发时启动一个服务。该服务在每个应用程序的顶部有一个覆盖视图(类似于Facebook聊天头像)。当点击导航软键按钮(后退、主页和最近使用的应用程序)时,我希望停止服务并移除覆盖视图。
我已成功地通过扩展RelativeLayout创建了一个覆盖视图,而且它完全正常工作。我正在遵循this中的覆盖视图指南。
Facebook也在做相同的事情来展开和关闭聊天头像。提前感谢你的帮助。 :) 编辑 我的问题与here中所述的问题相同。
2个回答

10

我和你一样也遇到了同样的问题。所以经过几天的研究,我找到了下面这个类,用于检测(Home键和Recent Apps键的按下事件)。

public class HardwareKeyWatcher {
    static final String TAG = "HardwareKeyWatcher";
    private Context mContext;
    private IntentFilter mFilter;
    private OnHardwareKeysPressedListener mListener;
    private InnerReceiver mReceiver;


    public interface OnHardwareKeysPressedListener {
        public void onHomePressed();

        public void onRecentAppsPressed();
    }

    public HardwareKeyWatcher(Context context) {
        mContext = context;
        mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        mFilter.setPriority(1000);
    }

    public void setOnHardwareKeysPressedListenerListener(OnHardwareKeysPressedListener listener) {
        mListener = listener;
        mReceiver = new InnerReceiver();
    }

    public void startWatch() {
        if (mReceiver != null) {
            mContext.registerReceiver(mReceiver, mFilter);
        }
    }

    public void stopWatch() {
        if (mReceiver != null) {
            mContext.unregisterReceiver(mReceiver);
        }
    }

    class InnerReceiver extends BroadcastReceiver {
        final String SYSTEM_DIALOG_REASON_KEY = "reason";
        final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
        final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
                if (reason != null) {
                    Log.e(TAG, "action:" + action + ",reason:" + reason);
                    if (mListener != null) {
                        if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                            mListener.onHomePressed();
                        } else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                            mListener.onRecentAppsPressed();
                        }
                    }
                }
            }
        }
    }
}

在您的服务的onCreate方法中,如下使用上述类:

@Override
public void onCreate() {
 mHardwareKeyWatcher = new HardwareKeyWatcher(this);
        mHardwareKeyWatcher.setOnHardwareKeysPressedListenerListener(new HardwareKeyWatcher.OnHardwareKeysPressedListener() {
            @Override
            public void onHomePressed() {
                System.out.println("stop your service here");
            }

            @Override
            public void onRecentAppsPressed() {
                System.out.println("stop your service here");
            }
        });
 mHardwareKeyWatcher.startWatch();
}

同时,如果想要检测后退按钮,可以参考以下链接(Service with Overlay - catch back button press)。我尝试了这个解决方案,对我很有效。

所以你可以在 onHomePressed() 和 onRecentAppsPressed() 方法中调用 stopService(),然后在你的服务类中重写 onDestroy() 方法,如下所示。

@Override
public void onDestroy() {
  super.onDestroy();
  mWindowManager.removeView(mYourOverlayView);
  mHardwareKeyWatcher.stopWatch();
}

请尝试这些方法,并告知我们结果... 祝你好运。


你为我节省了好几天的时间。谢谢! - yarin

2
我认为Facebook使用Activity。当你点击Floating view时,可能会进入透明的activity。

2
是的,但活动的问题在于其会被延迟5秒钟。https://dev59.com/gW035IYBdhLWcg3wJccw - Ajeet
请尝试使用重定向Activity。就像这样:浮动视图->重定向Activity->Activity。 - takahirom
你能详细说明一下重定向 activity 的解决方案吗?谢谢。 - Ajeet
重定向活动非常简单。请将 startActivity()finish() 放置在重定向活动的 onCreate() 中。 - takahirom
重定向Activity有什么作用,你能解释一下吗?因为启动第一个Activity可能需要5秒钟的时间。 - Ajeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接