Android Dynamic RelativeLayout AddRules(); not working as expected - android

I am trying to show some views dynamically in a relative layout from a service. Basically, I am trying to get a TextView to show up right of an ImageView, like this:
ImageView TextView
What I actually get is:
TextView ImageView
(With that empty space. )
My variables:
private WindowManager windowManager;
private ImageView myImage;
private TextView myText;
private RelativeLayout myRelativeLayout;
private RelativeLayout.LayoutParams imageParams;
private RelativeLayout.LayoutParams textParams;
private WindowManager.LayoutParams relativeLayoutParams;
The service's onCreate method:
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
myImage= new ImageView(this);
myImage.setId(R.id.myImage);
myText= new TextView(this);
myText.setId(R.id.myText);
myRelativeLayout= new RelativeLayout(this);
myRelativeLayout.setId(R.id.myRelativeLayout);
final WindowManager.LayoutParams windowManagerParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
textParams= new RelativeLayout.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT
);
imageParams = new RelativeLayout.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT
);
relativeLayoutParams= new WindowManager.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
imageParams.addRule(
RelativeLayout.ALIGN_PARENT_LEFT |
RelativeLayout.ALIGN_PARENT_TOP, myRelativeLayout.getId());
//Tried without getId(),too
//If I omit ALIGN_PARENT_TOP here, the views are shown on top of each other
textParams.addRule(RelativeLayout.RIGHT_OF, myImage.getId());
windowManager.addView(myRelativeLayout, layoutParams);
myRelativeLayout.addView(myImage, imageParams);
myRelativeLayout.addView(myText, textParams);
// This does not appear to have any significance.
windowManager.updateViewLayout(myRelativeLayout, layoutParams);
The view ids are assined in an XML file. Trying to get it to run on API 14. The final puzzle will have plenty more views so I'd much rather stick to a relative layout.
I have read most anything I could find on the subject, but I can't figure out what I am doing wrong. I have tried setting gravity properties as well, but no luck. I will also need to handle click events later on. I have tried inflating the layout from an XML, and it works, but, as far as I understand, I can't access the views later on with this method.

LayoutInflater is right option and you can reach views as they are in windowManager and your service is not destroyed!

You should do like below,
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
myImage= new ImageView(this);
myImage.setId(R.id.myImage);
myText= new TextView(this);
myText.setId(R.id.myText);
myRelativeLayout= new RelativeLayout(this);
myRelativeLayout.setId(R.id.myRelativeLayout);
final WindowManager.LayoutParams windowManagerParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
textParams= new RelativeLayout.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT
);
imageParams = new RelativeLayout.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT
);
relativeLayoutParams= new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.TYPE_PHONE,
RelativeLayout.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
imageParams.addRule(
RelativeLayout.ALIGN_PARENT_LEFT);//RelativeLayout.ALIGN_PARENT_TOP
imageParams.addRule(
RelativeLayout.ALIGN_PARENT_TOP);
//Tried without getId(),too
//If I omit ALIGN_PARENT_TOP here, the views are shown on top of each other
textParams.addRule(RelativeLayout.RIGHT_OF, myImage.getId());
textParams.setMargins(0, 0, 0, 0);
windowManager.addView(myRelativeLayout, layoutParams);
myRelativeLayout.addView(myImage, imageParams);
myRelativeLayout.addView(myText, textParams);
// This does not appear to have any significance.
windowManager.updateViewLayout(myRelativeLayout, layoutParams);

Related

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

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

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);

App window and clickable background

When user start the application, I just want to show a button. User can continiue to use phone .
Example : (problem is icon is not clickable)
android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen"
http://developer.android.com/reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW
"android.permission.SYSTEM_ALERT_WINDOW" use this permission in main-feast
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Button btn = new ImageView(this);
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);
windowManager.addView(btn, params);

Move a window Manager?

I have a WindowManager set up like this.
myWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
myWindowManager.addView(view, params);
I add a View object to a WindowManager like this. I want to move this WindowManager to the TOP Center. I am not sure how I can do this. Any ideas?
You can set Gravity for you view. i.e.
myWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
//edited
params.gravity=Gravity.TOP|Gravity.CENTER_HORIZONTA;
myWindowManager.addView(view, params);
You can also check this for more details.

Categories

Resources