6

我创建了一个运行服务的应用程序。该服务基本上有一个覆盖按钮,点击按钮可以做一些事情。但是,每次单击按钮时,按钮背景中的应用程序都会响应。请问有人可以帮忙吗?

我提到了链接

这是我的代码:

服务代码:

public class HUD extends Service implements OnTouchListener{
    Button mButton;
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        String s;
        s = "Hari";

        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        //mView = new HUDView(this);
        mButton = new Button(this);
        mButton.setText("Overlay button");
        mButton.setOnTouchListener(this);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.RIGHT | Gravity.TOP;
        params.setTitle("Load Average");
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(mButton, params);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show();
        if(mButton != null)
        {
            ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mButton);
            mButton = null;
        }
    }
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Toast.makeText(this,"Overlay button event", Toast.LENGTH_SHORT).show();
        return false;
    }
}

清单也具有以下权限:

我尝试将类型更改为

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,

现在,无论我点击哪里,都会调用触摸事件。请问有人可以帮我吗?

4

2 回答 2

7

问题是您使用的是 WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY。我认为由于某些 Android 4.x 不再可用。这是我实现叠加按钮的方式:

public class OverlayButton extends Service implements OnTouchListener {

    Button mButton;
    WindowManager wm;

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

    @Override
    public void onCreate() {
        super.onCreate();

        mButton = new Button(this);
        mButton.setText("Overlay button");
        mButton.setTextColor(Color.BLACK);
        mButton.setOnTouchListener(this);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(150,
                     150, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.LEFT | Gravity.CENTER;
        wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(mButton, params);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(getBaseContext(), "onDestroy", Toast.LENGTH_LONG).show();
        if (mButton != null) {
            ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mButton);
            mButton = null;
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_UP) {
            Log.d("OverlayButton onTouch", "touched the button");
            stopSelf();
        }
        return true;
    }
}

我所做的是,如果我触摸他,我也给了他再次消失的能力。

这是我让他出现的方式:

getActivity().startService(new Intent(getActivity().getBaseContext(), OverlayButton.class));

但是,如果您从 Activity 启动它,只需使用:

startService(new Intent(this, OverlayButton.class));

并且不要忘记在清单中设置这些:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

在标签里面也不要忘记:

<service android:name="OverlayButton" ></service>
于 2013-10-23T15:01:01.350 回答
3

当您使用此WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH标志时,它会告诉应用程序监视您视图之外的所有触摸。

尝试WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL改用。这将仅拦截您的视图上的触摸。

要确认,您需要使用WindowManager.LayoutParams.TYPE_SYSTEM_ALERT使视图可点击。

于 2014-01-15T11:26:16.223 回答