触摸常驻屏幕的视图

3

我有一个总是显示在屏幕上(在其他应用程序之上)的视图,我想接收触摸事件并将它们传递下去。

来自运行中的 Service 的代码:

    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,  
            PixelFormat.TRANSLUCENT);

    v.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Toast.makeText(getApplicationContext(), "view touched", Toast.LENGTH_SHORT).show();
            return false;
        }
    });

    WindowManager localWindowManager = (WindowManager)getSystemService("window");
    localWindowManager.addView(v, localLayoutParams);

目前我无法获取触摸屏幕的输入。

2个回答

5
您希望将视图声明为TYPE_SYSTEM_ALERT,如下所示:
WindowManager.LayoutParams params =
        new WindowManager.LayoutParams(width, height, x, y,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;

这样它就只会对视图本身上的触摸做出响应。

此代码来自我设计的一个可工作的任务切换器。我没有使用FLAG_WATCH_OUTSIDE_TOUCH,因为当与我的覆盖层下方的其他窗口交互时,它会给我带来问题。


至于将触摸事件传递给其他应用程序-现在已经不再可能了,因为这代表着安全风险。

我最近就类似问题整理了更多细节,你可能会发现它很有趣:

此外,Edward Jezisek提到的一个有趣的库是pingpongboss的StandOut:

由于它是开源的,所以您可以查看代码以了解他正在做什么。


жҲ‘д»Қ然дёҚзҗҶи§ЈonTouchдәӢ件...еҪ“жҲ‘дҪҝз”ЁFLAG_WATCH_OUTSIDE_TOUCHж Үеҝ—ж—¶пјҢжҲ‘иғҪеӨҹдёҺе…¶д»–еә”з”ЁзЁӢеәҸиҝӣиЎҢдәӨдә’гҖӮ - RCB
1
抱歉,我在另一个地方有一个触摸监听器,它没有将事件传递给其他地方。<br/>目前,我正在尝试解决将事件传递给我的视图下面的视图(不是我的)的问题。根据您的回答,我了解到我无法做到这一点。因此,我正在尝试找到一种模拟触摸事件的方法来操作系统。 - RCB
你提到的应用程序中没有解决方案,因为它只处理其视图上的触摸事件,而不会将它们进一步传递。 - RCB
1
@RCB 我们刚刚添加了这些内容以备将来读者使用,因为这是有用的信息。至于传递事件的进一步操作-正如我所说的那样,如果没有 root 权限,则不应该进行此操作。 - Richard Le Mesurier

0

我不知道为什么,但是WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY会使你的视图无法触摸。

请改用WindowManager.LayoutParams.TYPE_PHONE

更新:

我忘了一件事。 如果你只设置WindowManager.LayoutParams.TYPE_PHONE,其他应用程序的View将无法被触摸。所以一定要添加WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE标志。


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