Android叠加来抓取所有触摸,然后传递它们?

问题描述 投票:23回答:4

我基本上试图从系统覆盖中获取所有触摸事件数据,根据此触摸数据移动我的精灵,然后允许OS /主屏幕/浏览器按照应有的方式对数据进行操作(反之亦然)。我发现了类似的问题,但没有任何东西可以引导我到任何我未曾去过的地方:

Getting the View that is receiving all the touch events

(已实施,结果如下)Creating a system overlay window (always on top)

我可以做什么:

我可以通过移动我的精灵并且不允许操作系统/主屏幕/浏览器看到它们中的任何一个来抓住所有触摸事件并对其进行操作,或者我可以允许触摸事件通过并且仅获得“TOUCH_OUTSIDE”我的应用程序要采取行动。

我未实现的目标:

我不能为我的生活找到一种方法来同时处理数据。我无法实现的唯一方法是:拦截我的APP中的数据并将其传递到OS / homescreen / browser以使用允许OS / homescreen / browser首先获取数据,然后以某种方式获取信息回调允许操作系统/主屏幕/浏览器获取数据,对数据进行操作,并轮询他们的滚动/位置值,以便在我的APP中对其进行操作。

我担心这是不可能的,我想我在某些文档中读到了一些我现在无法找到的内容:“无论是全部还是全无,您的视图都可以获取所有事件,或者都不是”

(为了避免混淆,我并不是说我有两个视图。我的意思是我有一个视图通过覆盖操作系统/主屏幕/浏览器的活动/服务来控制。如果你愿意,就像一块玻璃。)

感谢您提供的任何有用信息,非常感谢!

[更新]在下面的问题上发表我自己的文档,以免混淆。

android touch overlay touch-event
4个回答
15
投票

发现这个文档几乎说明不可能同时做到这两点:Android : Multi touch and TYPE_SYSTEM_OVERLAY

他们讨论了解决方法,但我认为它们中的任何一个都不会真正适用于我正在尝试做的事情。两者都将事件发布到底层应用程序,并且能够窥探它们以便为自己采取行动。

要创建叠加视图,在设置LayoutParams时,需要将类型设置为TYPE_SYSTEM_OVERLAY并使用标志FLAG_WATCH_OUTSIDE_TOUCH。这提出了一个问题,因为Android文档声明:“您不会收到完整的向下/移动/向上手势,只有第一个向下的位置作为ACTION_OUTSIDE。”为了接收完整的触摸事件数组,您需要使用TYPE_SYSTEM_ALERT类型,但这会导致叠加层接管屏幕并停止与其他元素的交互。

任何人都想不同意我很想听到好消息:-D


2
投票

您可以使用GestureOverlayView,如果您想要隐藏它绘制的线条,您可以将颜色设置为Transparent#00000000,这样它就不会显示,然后您可以捕获所有触摸和手势。

http://developer.android.com/resources/articles/gestures.html


1
投票

我在寻找同样的事情。

这个标志为我做了FLAG_NOT_TOUCH_MODAL

适用于Android 7和8设置,如下所示。

到目前为止,我实现的唯一操作是关闭覆盖窗口。

我还使用了Example System Overlay Code on Github的代码来获取事件。

顺便说一句,谷歌地图在Android 8上做得非常好。您可以拖动它们的叠加窗口,调整大小或关闭它。所有其他应用程序都可以正常工作。

    var type = 0

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
    {
        type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
    }
    else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
        type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
    }

    var flags = FLAG_NOT_TOUCH_MODAL

    mOverlayLayoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, type, flags, PixelFormat.TRANSLUCENT)

0
投票

这不是最佳解决方案,但可行。重新启动服务切换不可触摸的标志。将boolean extra添加到Intent,Intent用于启动服务以确定以前的状态切换值。更好的实现方式是在窗口监听时触发触摸意图,在不监听时触发固定时间段。

public class bleh extends Service {
    public void onCteqwer(int i) {

        Context context; Class <bleh> context1 = bleh.class;

        WindowManager.LayoutParams params = null;
        WindowManager mang = (WindowManager) getSystemService(WINDOW_SERVICE);

        //check previous state of service
        if(i==0)
            params = new WindowManager.LayoutParams(arg0,arg1,arg2,arg3,arg4,arg5);

        if(i==1)
            params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,arg0,arg1,arg2,arg3,arg4);

        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        View mViw = inflater.inflate(arg, null);

        mViw.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });

        mang.addView(mViw, params);

        Intent z = new Intent(context, context1);

        if(i==0)
            z.putExtra("name", 1);
        if(i==1)
            z.putExtra("name", 0);

        stopSelf();
        startService(z);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Bundle i=intent.getExtras();
        int userName = 0;

        if (i != null)
        {
            userName = i.getInt("name");
            onCteqwer(userName);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.