What is WindowManager in android?
Solution 1:
The Android WindowManager is a system service, which is responsible for managing the z-ordered list of windows, which windows are visible, and how they are laid out on screen. Among other things, it automatically performs window transitions and animations when opening or closing an app or rotating the screen.
Every activity has a Window that is used to display its content on the screen. When you call setContentView on an activity, it attaches that view to the activity's default window. The default window fills the screen, so that your activity's window hides any other activities -- the WindowManager will display whichever window is on top. So normally you don't need to worry about windows - you just create an activity and Android will do the rest for you.
But you need to interact with the WindowManager if you want to do something unusual like create floating windows that don't fill the screen. If you want to create a floating window that is visible in front of other applications, you can't use an activity because your activity will stop when another app comes to the foreground, and its window will be hidden or destroyed. Instead you need to display a window from a background service. For example:
WindowManager.LayoutParams p = new WindowManager.LayoutParams(
// Shrink the window to wrap the content rather than filling the screen
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
// Display it on top of other application windows, but only for the current user
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
// Don't let it grab the input focus
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// Make the underlying application window visible through any transparent parts
PixelFormat.TRANSLUCENT);
// Define the position of the window within the screen
p.gravity = Gravity.TOP | Gravity.RIGHT;
p.x = 0;
p.y = 100;
WindowManager windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
windowManager.addView(myView, p);
For this to work, you will need to add the following permission to your AndroidManifest.xml
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Solution 2:
For android api version > 23, android.permission.SYSTEM_ALERT_WINDOW
need to request runtime. Moreover, TYPE_SYSTEM_ERROR
and some few type is deprecated in android api 26. Here is the way
public void showWindowManager() {
if (requestPermission()) {
return;
}
WindowManager.LayoutParams p =
new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
Build.VERSION.SDK_INT > Build.VERSION_CODES.O
? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
: WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
LayoutInflater layoutInflater =
(LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
final View popupView = layoutInflater.inflate(R.layout.window_manager_layout, null);
windowManager.addView(popupView, p);
// dismiss windowManager after 3s
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
windowManager.removeView(popupView);
}
}, 3000);
}
@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {
showWindowManager();
}
}
}
public boolean requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
return true;
}
}
return false;
}