I am using window manager to show a popup from service, but my popup view is not visible. It is blank. Does someone have any idea why this is happening?
I have written android.permission.SYSTEM_ALERT_WINDOW permission in manifest too. My code looks like this.
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= 26) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else if (Build.VERSION.SDK_INT >= 22) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_TOAST;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
WindowManager.LayoutParams p = new WindowManager.LayoutParams(
// Shrink the window to wrap the content rather than filling the screen
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
// Display it on top of other application windows, but only for the current user
LAYOUT_FLAG,
// 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) context.getSystemService(WINDOW_SERVICE);
LayoutInflater layoutInflater =
(LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
binding = DataBindingUtil.inflate(layoutInflater, R.layout.activity_lock, null, false);
windowManager.addView(binding.getRoot(), p);
It requires 'draw over other apps' permission by the user. Please search in the settings for this permission and allow it for your app.
Related
I am using Window Service to draw Overlay over screen. But my Overlay not covering the whole screen, It leaves out Status bar and Navigation Bar.
I have tried different approaches to solve it, but didn't find any solution. But the solution is available, as some Apps (Edge Lighting) on Play Store drawing border over full screen(Even on Android O).
My code snippet to achieve the task.
Window Manager
int Layout_Flag;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Layout_Flag = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}else {
Layout_Flag = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
Layout_Flag,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(customView, params);
Drawing Edge
`override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// draw a shape
val width = measuredWidth
val height = measuredHeight
val strokeWidthCalculation = paint.strokeWidth / 2
path?.moveTo(strokeWidthCalculation, strokeWidthCalculation)
path?.lineTo(width - strokeWidthCalculation, strokeWidthCalculation)
path?.lineTo(width - strokeWidthCalculation, height - strokeWidthCalculation)
path?.lineTo(strokeWidthCalculation, height - strokeWidthCalculation)
path?.close()
paint.pathEffect = cornerPathEffect
canvas.drawPath(path!!, paint)
}`
Result
sample image, not covering status and navigation bar
In order to achieve it, the fourth parameter of WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS.
That's it.
The whole complete code:
val LAYOUT_FLAG: Int
LAYOUT_FLAG = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_TOAST
}
params = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
LAYOUT_FLAG, // NOTE
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT
)
My Android (8.0+) app is implementing a narrow overlay along the bottom of the screen, but when a user sets an overscan value, it disappears. How can I make my view respect what is actually visible so Gravity.BOTTOM will not be clipped? I have tried countless combinations of flags, but nothing seems to ackknowledge the overscan value.
Point screen_size = new Point();
WindowManager.LayoutParams mParams;
WindowManager mWindowManager = getSystemService(WINDOW_SERVICE);
mWindowManager.getDefaultDisplay().getRealSize(screen_size);
layout = new LinearLayout(getApplicationContext());
layout.setOnTouchListener(this);
// color for debug.
layout.setBackgroundColor(0x55ff0000);
mParams = new WindowManager.LayoutParams(
screen_size.x,
40,
0,
0,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
mParams.gravity = Gravity.BOTTOM;
mWindowManager.addView(layout, mParams);
i m trying to put window manager( using service not activity) over lockscreen and it works fine in other device except oreo device...in oreo device it display after lock screen.here is my permision foe window manager..so please suggest other solution to resolve the issue.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
}
mParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
LAYOUT_FLAG,WindowManager.LayoutParams.FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_LAYOUT_STABLE,
PixelFormat.TRANSLUCENT);
mParams.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
mParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
I am using Android window-manager to display an overlay image onto the users phone, but it is not setting the ImageView in the correct location, it always defaults to the center of the screen. I know the location is correct cause I have used accessibility services to touch the location and with show touches turned on in my phone it is touching the correct location. So why will the imageview not go to this location?
I get the location of the where I want to place the image from and imageview in my app:
Point centerPoint = getCenterPointOfView(myImageView);
int xImageLocation = centerPoint.x;
int yImageLocation = centerPoint.y;
And then I open the new overlay with this:
//Add the view to the window.
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.x = xImageLocation;
params.y = yImageLocation;
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
if (mWindowManager != null) {
mWindowManager.addView(mFloatingView, params);
}else {
return;
}
You need to set gravity of WindowManager.LayoutParams to Gravity.TOP | Gravity.LEFT.
As you've noticed by default its set to Gravity.CENTER, so with x=0 and y=0 your mFloatingView should be exactly in the middle of the screen.
In my app I use a BroadcastReceiver to catch incoming calls. So when someone calls and in case that I have the phone number stored in my application's DB, I display a window with the name of the caller.
The problem is that in some devices this window is not displayed if the device's screen is off before the phone rings.(If the screen of the device is on, when the phone rings, the window is displayed).
I also delay the drawing of the window for 3 seconds, but this doesn't seem to work.
To display the window I use the following code, where mView is a RelativeLayout with a TextView. This code runs in a Service.
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
dpToPx(72),
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
mParams.gravity = Gravity.TOP;
WindowManager mWindowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
mWindowManager.addView(mView, mParams);
After several failing tries I found it.
I had to replace the flag TYPE_PHONEwith TYPE_SYSTEM_OVERLAY.
try this, this will surely work
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Layout_Flag = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Layout_Flag = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Layout_Flag = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
Layout_Flag,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER;
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
try {
mWindowManager.addView(windowView, params);