How to Create Always-Top Fullscreen Overlay Activity in Android

How to create always-top fullscreen overlay activity in Android

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);

WindowManager wm = (WindowManager) getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);

ViewGroup mTopView = (ViewGroup) App.inflater.inflate(R.layout.main, null);
getWindow().setAttributes(params);
wm.addView(mTopView, params);

How do I make my full-screen overlay remain full-screen after orientation changes?

I was misled by the answer to a previous question "How to create always-top fullscreen overlay activity in Android". Maybe it worked for an older API level? I'm using API level 24.

That particular answer had recommended:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
);

There is a problem with this. The constructors that exist for WindowManager.LayoutParams are as follows:

Sample Image

So the WindowManager.LayoutParams.FLAG_FULLSCREEN flag gets used as an explicit value for int w and int h. This is no good!


I found that the correct construction for a full-screen overlay is like so:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // TYPE_SYSTEM_ALERT is denied in apiLevel >=19
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT
);

This means we no longer explicitly specify a width and height. The layout relies entirely on our flags instead.

Yes, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN is a required flag still; it is necessary if you want to draw over decorations such as the status bar.

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY should be used instead of TYPE_SYSTEM_ALERT in API level >=19.


Bonus notes (if you're reading this, you're probably trying to make a full-screen overlay):

Your manifest will need the following permissions (explanation here):

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

My understanding is that SYSTEM_ALERT_WINDOW is the actual permission required, but that ACTION_MANAGE_OVERLAY_PERMISSION is needed also: it lets you request at runtime that the user grant the SYSTEM_ALERT_WINDOW privilege.

Creating a system overlay window (always on top)

This might be a stupid solution. But it works. If you can improve it, please let me know.

OnCreate of your Service: I have used WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH flag. This is the only change in service.

@Override
public void onCreate() {
super.onCreate();
Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
mView = new HUDView(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
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(mView, params);
}

Now, you will start getting each and every click event. So, you need to rectify in your event handler.

In your ViewGroup touch event

@Override
public boolean onTouchEvent(MotionEvent event) {

// ATTENTION: GET THE X,Y OF EVENT FROM THE PARAMETER
// THEN CHECK IF THAT IS INSIDE YOUR DESIRED AREA

Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
return true;
}

Also you may need to add this permission to your manifest:

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

Android - how to create an overlay fullscreen including Action Bar

maybe this open-source library is what you're looking for:

Showcase View

Sample Image

You can grab the source code and setup instructions from GitHub.

hop to be usefull :)

Android - Making activity full screen with status bar on top of it

I know that the guy asking the question may have found his own solution but for the people who are still looking for a solution this is a very simple solution but one thing it has a limitation till Kitkat so a condition is added

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

how to make system overlay full height

Simply Change 'FLAG_FULLSCREEN' to 'MATCH_PARENT'.

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);

Or to remove the system ui(Status & Nav Bar) from view too:

    int KitKatFlags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;

getWindow().getDecorView().setSystemUiVisibility(KitKatFlags);

How to make an activity window stay always on top

You can't. As this is defined in the Android system.

Full screen TYPE_ACCESSIBILITY_OVERLAY

What you seem to be missing is flagRetrieveInteractiveWindows on your configuration. These properties and window layout paremeters configuration should work, without requiring for you to disable canRequestTouchExplorationMode in order to get the events and having getWindows return the AccessibilityWindowInfo instances underneath yours:

    <?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:packageNames="test.demo.com.tests"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagRetrieveInteractiveWindows|flagReportViewIds|flagIncludeNotImportantViews"
android:accessibilityFeedbackType="feedbackAllMask"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>

And on service connected:

    @Override
protected void onServiceConnected() {
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
FrameLayout layout = new FrameLayout(this);

WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS|
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP;

windowManager.addView(layout, params);
layout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//You can either get the information here or on onAccessibilityEvent
return false;
}
});
}

EDIT:

Added FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS to accomplish full screen and removed canRequestTouchExplorationMode since the flag associated to this property should not be included and, therefore, of no use.

How to do overlay animation for Android that is active in any Android screen?

What you're looking for is called a system overlay window.

There have been many questions about this in the past; perhaps you'll find an answer by looking at these:

  • Creating a system overlay window (always on top)
  • How to create always-top fullscreen overlay activity in Android

It essentially comes down to:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams( 
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);

WindowManager wm = (WindowManager)
getApplicationContext().getSystemService(Context.WINDOW_SERVICE);

ViewGroup view = (ViewGroup) App.inflater.inflate(R.layout.overlay_view, null);
getWindow().setAttributes(params);
wm.addView(view, params);


Related Topics



Leave a reply



Submit