Android overlapping views when using WindowManager - android

I'm using WindowManager to add views to the users screen using an IntentService, as shown here:
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.BOTTOM | Gravity.CENTER;
params.x = 0;
params.y = 100;
windowManager.addView(cardView, params);
When I first launch the IntentService, the view is created as expected. However, when I re-launch the IntentService, a new view is added but the previous view remains.
How can I remove all the views that I have already added before adding a new view? I know that if I kill the IntentService then the views disappear, but how do I delete all other instances of my IntentService except the instance that I have just launched?
This is what it looks like when I first call the IntentService:
By the time the IntentService has been called multiple times, a shadow appears because there are so many view stacked on top of each other:

When the service ends, you need to remove your previous views in the onDestroy() function.
if(cardview!=null){
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.removeView(mView);
}

Related

TYPE_STATUS_BAR overlay makes system ignore screen timeout

Goodmorning,
i'm developing an overlay which is posted by a service.
The problem is that the screen stays always on, even after screeen timeout expires.
This is my code:
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.TYPE_STATUS_BAR|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity= Gravity.TOP | Gravity.LEFT;
overlay.setKeepScreenOn(false);
wm.addView(overlay, params);
I've already tried to add WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, but no luck.
Thanks for your help.
The solution is not to use WindowManager.LayoutParams.TYPE_STATUS_BAR
but one with lower privileges as this is only used by the system.

Permanent app tile on home screen

I'm creating an app for a limited audience inside my company.
I'd like to have an icon or tile (icon + text) which remains on the home screen (on top of other things) which will allow people to come back to my app.
Something like this:
Is it possible to program something similar?
I ended up using a system alert window.
Just in case anyone is interested in doing the same thing - here's the code:
WindowManager wm = (WindowManager) context.getSystemService(activity.WINDOW_SERVICE);
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.TOP;
TextView textView = new TextView(context);
textView.setText("Touch to return to my app");
wm.addView(view, params);
Thanks!

Receive touch event on any screen

I'm trying to make a custom navigation button and have disabled the default navigation buttons provided by android by rooting my device. I want my custom navigation buttons to disappear after some interval of time (say 5 seconds). I have managed to do so. I want to make something such that whenever I touch anywhere on the screen, I can detect the touch event and show my navigation bar. Whether I'm on homescreen or any application, I can receive touch event. Is there a way to do so or do I need to go android source code?
Thank you
OnCreate of your Service: used WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH flag.
#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.
see this Creating a system overlay window (always on top)

How to make a Facebook Messenger-like notification like this in Android

I want to implement notifications like the one in the following image.
Notification appears any time. I think it's of course a background service waiting for new messages from the server then shows this. What I think this is an activity implemented as dialog with this custom UI. Am I correct? And is it a normal startActivity method from the service? And how do I do the transition animation to make it appears slowly from left to right with zooming when show up?
Check out this link http://www.piwai.info/chatheads-basics. He provides information about how to add them on your screen.
The trick is to add a View to the WindowManager like following code
private WindowManager windowManager;
private ImageView chatHead;
public void addView()
{
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.android_head);
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.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
windowManager.addView(chatHead, params);
}
Don't forget to add the permission <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

Switching between TYPE_SYSTEM_ALERT AND TYPE_SYSTEM_OVERLAY , and capturing the touch events not working properly

I made a View in service which runs always on top of every application in android.
Initially, the behaviour of service is TYPE_SYSTEM_ALERT .
WindowManager.LayoutParams layparams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
layparams .gravity = Gravity.CENTER_VERTICAL| Gravity.CENTER_HORIZONTAL;
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(serviceView, layparams );
I am changing the behaviour of service at run time means switching between TYPE_SYSTEM_ALERT AND TYPE_SYSTEM_OVERLAY on touch. Switch take place when I touch outside the view parameters and when touch inside the view parameters.
layparams .type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
Using updateViewLayout(serviceView, layparams )
PROBLEM: Is when I touch outside of view , the first touch just activate TYPE_SYSTEM_OVERLAY and after then outside app works fine. When TYPE_SYSTEM_OVERLAY is working , after that when you touch within the view it will trigger the action of object behind the view not the action of the view. But when u once touch the view TYPE_SYSTEM_ALERT will be applied and now the View will behave normally .
Current Implementation : I have to touch twice to work that particular thing when switch take place between layout parameters.
use this one... works perfectly on ICS and above
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;//This one is necessary.
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
params.gravity = Gravity.TOP | Gravity.RIGHT;
params.x = 0;
params.y = -params.height;
windowManager.addView(tile, params);
you can do this by calling updateViewLayout() on instance of WindowManager class.
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
// create new layout params
WindowManager.LayoutParams newlayparams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
//update new layout
wm.updateViewLayout(serviceView, newlayparams);
Hope it help!

Categories

Resources