I'd like to draw a (mouse pointer) icon on screen over the other applications from a service. I have implemented the functionality and I can draw over the screen, apart from the navigation bar. I've researched several other questions here and tried TYPE_SYSTEM_OVERLAY
, TYPE_TOAST
, TYPE_SYSTEM_ERROR
and some other window types without success.
I'm not trying to capture focus, just drawing a mouse pointer on the screen for a second or two. When I try to draw over navigation bar, it just goes under (actually, the RelativeLayout ends on the border with navigation bar - even when I specify manual dimension for height). The screenshot below shows the hand pointer in the lower right part of the screen. That's as low as I can position it. Note that I'm not trying to hide the navigation bar in my application - trying to draw over other apps.
I even tried setting the xpos
and ypos
offset settings in WindowManager.LayoutParams
instance, but that just offsets the layout and still goes below the navigation bar).
The layout params I'm using to show this window:
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSPARENT);
I am then adding the RelativeLayout
with those parameters to the WindowManager: windowManager.addView(relativeLayout, params);
The navigation bar at the bottom is something that cannot be drawn over because the items drawn above might impede access to the home button, back button, etc. But you can make your activity full-screen, meaning that it will hide the navigation buttons until you swipe up from the bottom, so that you can be free to draw anywhere on the screen
EDIT: I found some similar questions and this one has an answer : Draw bitmaps on top of the Navigation bar in Android The answer was to add a y offset that's the size of the navigation bar.
After a lot of fiddling, I've managed to get the right flags to make it work. It almost works (for most apps). The code to achieve follows (an example on button click handler):
@Override
public void onClick(View view) {
if (_windowManager == null) {
_windowManager = (WindowManager) MainActivity.this.getSystemService(Context.WINDOW_SERVICE);
}
WindowManager.LayoutParams params;
// create the view on the first try
if (_overlayView == null) {
ImageView hand;
_overlayView = new FrameLayout(MainActivity.this);
hand = new ImageView(MainActivity.this);
hand.setImageResource(R.drawable.icon_hand_pointer);
int w = hand.getDrawable().getIntrinsicWidth();
int h = hand.getDrawable().getIntrinsicHeight();
_overlayView.addView(hand);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
params.width = w;
params.height = h;
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = _xOffset;
params.y = _yOffset;
_windowManager.addView(_overlayView, params);
} else {
// move the view
params = (WindowManager.LayoutParams) _overlayView.getLayoutParams();
params.x = _xOffset;
params.y = _yOffset;
_windowManager.removeView(_overlayView);
_overlayView.setLayoutParams(params);
_windowManager.addView(_overlayView, params);
}
_xOffset += 40;
_yOffset += 100;
}
Here is a screenshot of this code working in an app (you can see the hand overlay; this is on Nexus 5 with Android 6.0.1:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With