Android window manager - view above all activities - android

I'm trying to open a view with WindowManager, a view that will be above all the activities of my app, but not above other apps.
This is what i have so far:
WindowManager.LayoutParams layOutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT);
layOutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layOutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
LayoutInflater layOutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
View viewAboveAllActivities = layOutInflater.inflate(R.layout.activity_flash_alert_layout, null);
wm = (WindowManager) context.getSystemService(WINDOW_SERVICE);
wm.addView(viewAboveAllActivities, layOutParams);
I have no idea what are the right layout params that will fit my needs, hope you guys can help.

Related

How to change Screen overlay after system ui mode changed(Fullscreen, hide navigation)?

I create overlay:
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
/*The parent view (actually the root view) the will be added in front of all the windows on the screen*/
mOverlayView = (RelativeLayout) inflater.inflate(R.layout.overlay_control, null);
mWindowManager.getDefaultDisplay().getSize(size);
mWindowSize = new Size(size.x, size.y);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
mWindowManager.addView(mOverlayView, params);
I need to move overlay if system UI Visibility changed. There is possibility to detect it(documentation) for view but it not works for overlay. So I only need callback to detect if mode of device changed.
I found the way to do it:
In Android there is OnSystemUiVisibilityChangeListener but it not works if there is not view which will has match_parent value of width or hight.
So I created such overlay and made it 1 px height and match_parent width and add OnSystemUiVisibilityChangeListener to it.

Issue with updating view inside WindowManager in Android

Here is the code for adding WindowManager to stay on top of other views.
private View mainView;
private WindowManager.LayoutParams params;
windowManager = (WindowManager) getSystemService(Service.WINDOW_SERVICE);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 0;
windowManager.addView(mainView, params);
It works fine. Inflating a layout inside the window manager and updating the layout dynamically. But I am unable to update the view.
LayoutInflater inflater = LayoutInflater.from(CallTimerService.this);
mainView = inflater.inflate(R.layout.call_dialog, null);
callerNameTv = (TextView) mainView.findViewById(R.id.caller_name);
callerNameTv.setText(name);
setText method is called and there is no exception but the view is not updated. Can anyone point out the issue here?
Update the specific view you wish to modify:
// Get the view params
WindowManager.LayoutParams paramNameTV = (WindowManager.LayoutParams) callerNameTv .getLayoutParams();
//update the view layout
windowManager.updateViewLayout(callerNameTv, paramNameTV);

How to add an activity to WindowManager

I am writing an android library that needs to display an activity on top of the client app. After some reading up it seems that adding a new window is what I want to do so I added in this permission.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
I then try to add an image view by doing this
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.BOTTOM | Gravity.LEFT;
params.x = 10;
params.y = 100;
ImageView imageview = new ImageView(this);
imageview.setImageResource(R.drawable.avatar);
windowManager.addView( imageview , params);
But what I want is to have my own activity on this new window on top of the client apps window. is this even possible? How would I do this?
Ok the correct approach to this appears to be to inflate the layout with in the service class and add it to the windowmanager that way. Then create a regular java class that can be used as the event listeners for the actions within that layout. I didnt need to use fragments or activities.
mRootLayout = (LinearLayout) LayoutInflater.from(context).
inflate(R.layout.myContainerXML, null);
MyListManager myListManager = new MyListManager(mRootLayout,context);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
ListView listView = (ListView) mRootLayout.findViewById(R.id.listView);
final MyListAdapter adapter = new MyListAdapter(activity,R.layout.list_row,(ArrayList)myListManager.getList());
listView.setAdapter(adapter);
windowManager.addView(mRootLayout, params);
If anyone has a better way I would love to hear it thanks

The back button is not working when a layout is overlayed using WindowManager. How to make it work?

LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY | WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.RIGHT | Gravity.TOP;
myview = li.inflate(R.layout.locked_layout, null);
wm.addView(myview);
This is the code I have used for overlaying a layout over a screen. Only the HOME button is working. But the BACK button is not working. I want both to work. Am I missing anything? Please help me!! Thanks in advance
Add this flag as well my friend:
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
This worked for me!!
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindwoManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.RGBA_8888);
params.gravity = Gravity.RIGHT | Gravity.TOP;

How to overlay a crosshair

I have seen many applications where the user touches the screen and the application displays an overlay crosshair view of the point. I would please like to know how this works and how to overlay it such as in the developer option in the phone, where it overlays every screen. Thank you.
If you want overlay everything, not just your application, call code like this from service.
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
LayoutInflater layoutInflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = layoutInflater.inflate(R.layout.whatToShow, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT;
params.x = 0;
params.y = 0;
windowManager.addView(mView, params);
And to remove it
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView);
It requires following line in manifest:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Also check out this tutorial
http://www.piwai.info/chatheads-basics/
You can inflate a layout as a View and add view to the root view.
inflater = LayoutInflater.from(getBaseContext());
View view = inflater.inflate(R.layout.overlay, null);
LayoutParams layoutParamsControl= new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
this.addContentView(view, layoutParamsControl);

Categories

Resources