Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Overlay button onClick is never getting called

I have created an application that runs a service. The service basically has an Overlay button and the button on click does something. However, everytime, I click on the button, the application in the background of the button is responding. Please can someone help?

I have referred to link.

Here is my code:

Service code:

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;
    }
}

The manifest has the following permission as well:

I tried changing the types to

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,

Now, wherever I click, the touch event is getting called. Please can someone help me?

like image 693
Hariprasauth Ramamoorthy Avatar asked Jul 23 '13 13:07

Hariprasauth Ramamoorthy


2 Answers

The problem is you are using WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY. I think since some Android 4.x it is not usable anymore. This is the way i realized an overlay Button:

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;
    }
}

What i did is, i also gave him the ability to disappear again, if i touch him.

This is the way i let him appear:

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

but, if you start it from your Activity, just use:

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

And don't forget to set these in your manifest:

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

And inside the tags also don't forget:

<service android:name="OverlayButton" ></service>
like image 130
qweret Avatar answered Sep 18 '22 12:09

qweret


When you use this WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH flag, it is telling the app to watch for all touches outside of your view.

Try using WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL instead. This will intercept touches only on your view.

To confirm, you need to be using WindowManager.LayoutParams.TYPE_SYSTEM_ALERT to make the view clickable.

like image 33
Richard Le Mesurier Avatar answered Sep 20 '22 12:09

Richard Le Mesurier