14

我有一个启动系统覆盖的服务。当覆盖层可见时,我希望它是可触摸的/检测触摸,但我想保留与它后面的屏幕的交互(后面是指底层活动,例如覆盖层旁边)。

我的叠加层是 128x128px 的位图/PNG。它被绘制,当我点击它时,我收到了 TOUCH!日志,这很好。但是当我点击屏幕的任何其他部分(除了覆盖)时,我也会得到 TOUCH!记录并且不可能与下面的屏幕进行交互。

以下是我的代码部分:

启动服务的主要活动

buttonStart.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // start Service and return to Homescreen
                Intent i = new Intent(MainActivity.this, MyService.class);
                startService(i);                

                Intent newActivity = new Intent(Intent.ACTION_MAIN); 
                newActivity.addCategory(Intent.CATEGORY_HOME);
                newActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(newActivity);
            }
        });

服务/显示叠加

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        myOverlay = new Overlay(MyService.this);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.LEFT | Gravity.TOP;

        wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(myOverlay, params);

        myOverlay.setAnimation(new Waiting(MyService.this, 0, 0));
        myOverlay.postInvalidate();

        return super.onStartCommand(intent, flags, startId);
    }

覆盖

public MyOverlay(Context context) {
        super(context);     
        this.context = context;

        setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.i("TOUCH!", event.getAction() + ", x:"+event.getX()+", y:"+event.getY());
                return false;
            }
        });
    }

我究竟做错了什么?还尝试了 WindowManager.LayoutParams.TYPE_PHONE 而不是 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,但行为相同。

我没有使用标志 FLAG_WATCH_OUTSIDE_TOUCH,那么为什么没有在覆盖层旁边注册触摸?

编辑

看来我找到了问题,但仍然不知道如何解决它......覆盖中显示的图像真的很小而且不是问题,但覆盖本身是全屏的(!)

我在 Overlay / onTouch() 事件中添加了以下日志:

Log.i("TOUCH!", "View: "+v.toString() +", size="+ v.getWidth()+"/"+v.getHeight());

然后告诉我 View: package.overlay.myOverlay, size=480/762

现在我试图通过在服务中添加以下行来强制它不是全屏:

    @Override
        public int onStartCommand(Intent intent, int flags, int startId) {

            myOverlay = new Overlay(MyService.this);
//HERE
myOVerlay.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

            WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 
                    PixelFormat.TRANSLUCENT);
            params.gravity = Gravity.LEFT | Gravity.TOP;

            wm = (WindowManager) getSystemService(WINDOW_SERVICE);
            wm.addView(myOverlay, params);

            myOverlay.setAnimation(new Waiting(MyService.this, 0, 0));
            myOverlay.postInvalidate();

            return super.onStartCommand(intent, flags, startId);
        }

但这无济于事... myOverlay 的大小仍然为 480x762... 为什么它那么大,我怎样才能让它具有包含图像的大小?

4

3 回答 3

14

这对我有用:

WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

View将 LayoutParams 添加到时使用此 LayoutParams WindowManager,它会阻止它接收任何点击,这可能TYPE_TOAST就足够了,但我添加了标志只是为了确保。

于 2014-10-27T06:51:17.380 回答
2

我也遇到了同样的问题,我通过设置 params.width 和 params.height 解决了这个问题。尝试这个。

params.width = 128;
params.height = 128;

我希望它会有所帮助。

于 2013-12-12T01:55:48.537 回答
-2

我遇到了同样的问题,只需尝试将其添加到您的代码中:

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY

我非常有信心代码可以正常工作,如果它不仅检查代码是否有其他错误,而且就触摸而言,这是您的解决方案。无论如何,请告诉我。我几乎忘记了第二部分,只需将属性更改为 matchparent 而不是 wrapcontent。

祝你好运

于 2013-10-19T15:09:54.207 回答