Draw over navigation bar (and other apps) on Android version >= 5
Asked Answered
S

2

14

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.

overlay-pointer-on-screen

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

Sixth answered 20/7, 2015 at 12:6 Comment(2)
Did you declare permission draw over other apps on your manifest file?Waldner
@Waldner yes, of course. Otherwise I wouldn't be able to draw at all. I can draw fine, over the status bar as well, just not over the navigation bar (bottom, where back, home and recent softkeys are)Sixth
S
11

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: enter image description here

Sixth answered 3/9, 2015 at 13:18 Comment(5)
Also see the following comment about not always being able to draw over navbar.Sixth
Did you ever find a way to get it working in all apps? I can't get mine to draw over the navbar in certain apps like Chrome and Tinder profile view mode only! It simply draws under the navbar.Sacristan
@Flyview, no, I didn't; We ended up with this solution in the end.Sixth
@Sixth does this work? can you please post a screenshot?Representative
@KarunShrestha, it works. You can actually test it within ISL Light app (available on Play). I'll try to add a screenshot into above answer as well.Sixth
I
3

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.

Ides answered 29/8, 2015 at 5:20 Comment(4)
TeamViewer QS app can do that. The idea is to draw over other apps, not so much over own activity.Sixth
@Sixth it looks like its makes a quick screenshot and then lets the techinician draw over the screen, and then let the user take control again.Ides
@user3911725 I just re-tested TeamViewer app - I don't believe it is using screenshots, as I can interact with the launcher or app while TV is overlaying the pointer. I did find the answer you linked before, but that does not work unfortunately (or I'm missing a key ingredient).Sixth
@Sixth I need to this with Android Keyboard. If you have achieve. Please let me know.Rabat

© 2022 - 2024 — McMap. All rights reserved.