Showing a view in WindowManager that can come from "out of screen" - android

I'm having the following issue - I'm having a view that I'm putting inside the WindowManager
and I would like it to come in translate animation from out of the screen and toward the middle of the screen.
Unfortunately, no matter what I do the view sticks to the axis.
This is the code:
view = (FrameLayout) LayoutInflater.from(this).inflate(
R.layout.poke, null);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
300, 400, WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.verticalMargin = -10f;
params.gravity = Gravity.TOP;
windowManager.addView(view, params);
As you can see I tried playing with the margin (put there minus to make it go up).
By the way - I know that it's ugly to put numbers and not dp in dimen.xml. Its just a test code..

I just faced the same issue and the actual flag is:
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
So your code should look like:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
300, 400, WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);

In the flags that you are specifying, add another flag FLAG_LAYOUT_NO_LIMITS.
That should allow you to place your views even outside the screen.
Your code should look like this:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
300, 400, WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);

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.

Chat head kind of pop up with edit text. But key pad not coming up when clicked inside

I have implemented chat head kind of pop up for my application using service. And I have used edit text inside that.
But problem is that when I click on edit text only cursor is visible and keyboard is not coming up. And not even able to select or copy paste the text inside that edit text. Any help? Thanks
I found solution to my problem.
I was using the following code earlier:-
Global variables:-
private WindowManager mWindowManager;
WindowManager.LayoutParams params;
Then in onCreate of Service
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
//Add the view to the window.
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
Problem was with FLAG_NOT_FOCUSABLE, use FLAG_NOT_TOUCH_MODAL instead.
But now again problem was that though I was able to get the keyboard with my floatingView but keypad was not coming for other apps, even back button stopped working.
So to fix this I used button on Floating UI which toggles between enabling keypad on floating UI and disabling that so that back button and keypad works for other apps.
I used the following code for the same:-
private void enableKeyPadInput(Boolean enable) {
mWindowManager.removeViewImmediate(mFloatingView);
if (enable) {
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
} else {
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
}
mWindowManager.addView(mFloatingView, params);
}
If true is passed to this method then keypad starts working. If false is passed then other apps starts working.
This is my workaround for the problem. Is there any other way to achieve the same which is better than this?
thank #Narendra Jadon
this maybe better
private void enableKeyPadInput(Boolean enable) {
//mWindowManager.removeView(mFloatingView);
if (enable) {
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
} else {
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
}
mWindowManager.updateViewLayout(mFloatingView,params);
//mWindowManager.addView(mFloatingView, params);
}

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.

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

Android Create "Ghost" Image (Touch-through)

I have created a service which will overlay an image on top of the whole screen.
This part is the code which will overlay an image on top of the whole screen:
#Override public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
img = new ImageView(this);
img.setImageResource(R.drawable.image); // Image is .png format
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.CENTER | Gravity.CENTER;
params.x = 0;
params.y = 0;
windowManager.addView(img, params);
}
However, any space which the image covers in untouchable. I want the image to be just overlaid, without affecting any other components on the screen, similar to what this does:
How can I make the area beneath the image touchable (touch-through)?
Edit
It seems that the transparent space of the image fills a square, and covers the screen (FYI).
So my ultimate goal is, to make the image touch-through.
I have tried the popupWindow class, recommended by a few SO users, but its purpose does not fulfill my needs and does not work.
I found that WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY solves the issue.
Try
img.setClickable(false);
http://developer.android.com/reference/android/view/View.html#setClickable(boolean)
Try setting the param flags to:
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
I've tried this with success before. The last two will help send touch events to the views behind it.

Categories

Resources