Good day.

There is a need to draw a custom mouse. First of all, of course, I googled for the presence of similar applications and did not find anything other than Tap Pointer , which requires root and at the same time works just awful (at least on my Nexus 5 with Android 7.1).

After that, I decided to make my own application, but since I'm new to Android programming, some questions immediately came up. With this and this, I was able to achieve drawing on top of almost all windows. But it was not possible to achieve drawing on top of navigation. I read that starting from API 23 there are problems with this, but I know that there are ways to do it. There is a Twilight application that covers the entire screen with a red filter, including navigation.

In addition, I can not make a clickable button in the overlay. Touch and click events are simply not caught.

The code that I got is:

public class MousePointerService extends Service { private WindowManager wm; private PointerView pointerArea; private Button overlayButton; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Toast.makeText(getBaseContext(), "onCreate", Toast.LENGTH_SHORT).show(); wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); pointerArea = new PointerView(this); pointerArea.setBackgroundColor(0x33aaddff); // Заполнить всю область полупрозрачным голубым, чтобы понять где можно рисовать WindowManager.LayoutParams pointerAreaParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.TRANSLUCENT); wm.addView(pointerArea, pointerAreaParams); overlayButton = new Button(this); overlayButton.setText("Test"); overlayButton.setBackgroundColor(Color.DKGRAY); overlayButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Это событие никогда не вызывается Toast.makeText(getBaseContext(),"onClick", Toast.LENGTH_SHORT).show(); } }); overlayButton.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // И это событие тоже почему-то никогда не вызывается Toast.makeText(getBaseContext(),"onTouch", Toast.LENGTH_SHORT).show(); return false; } }); WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); params.gravity = Gravity.CENTER; wm.addView(overlayButton, params); } @Override public void onDestroy() { super.onDestroy(); Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_SHORT).show(); if (overlayButton != null) { wm.removeView(overlayButton); overlayButton = null; } if(pointerArea != null) { wm.removeView(pointerArea); pointerArea = null; } } } public class PointerView extends View { private Paint paint; PointerView(MousePointerService context) { super(context); paint = new Paint(); paint.setColor(Color.DKGRAY); paint.setAlpha(127); paint.setStrokeWidth(60); paint.setStrokeCap(Paint.Cap.ROUND); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawPoint(100, 100, paint); // Пробуем отрисовать что-нибудь в кастомном View } @Override public boolean onTouchEvent(MotionEvent event) { // Это событие никогда не вызывается Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show(); return true; } } 

Also, there is the following permission:

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

And in the settings of the application, rights are granted to superimpose on all windows.

Result screenshot:

Result

As you can see, the point was drawn, the button too, and the entire screen, with the exception of the navigation bar, was requested by a translucent blue. And the button is not clickable.

Now briefly questions:

  1. How to draw something over the navigation? Yes, even so that it fits Android 4.0+
  2. How to catch all touch events? In order to control a custom mouse from anywhere. (And can this be done without root)
  3. How to make the button feel pressed?

I know that the android has its own cursor, but I couldn’t find anything useful about it, but from what I found I got the impression that it’s impossible to do without it.

PS Perhaps the questions are stupid or my problem can be solved much easier, please indicate to me if this is so.

This question on the English-language site "System overlay. How can I catch touch events?"

  • Added a code and a screenshot of the application. Also made a copy of the topic on the English-language site. If they answer - I will write a solution here. - OsipXD

0