Is it possible to draw an entire activity over another app? - android

Say your app has the permission to draw over other apps. You can draw a Drawable over anything with this simple code:
private void drawTheOverlay(Drawable drawable) {
WindowManager windowManager = (WindowManager) this.getSystemService(Service.WINDOW_SERVICE);
View view = new LinearLayout(this);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
view.setBackground(drawable);
windowManager.addView(view, layoutParams);
view.setVisibility(View.VISIBLE);
}
My question is if you can draw an entire activity over another app? Meaning draw an activity, including its buttons, imageviews, child layouts, and everything in it, and make it interactable like an activity would be, but with a transparent background so that the app it's drawing over appears behind it. Is this possible?

Related

Android With WindowManager View not move down when soft keyboard hide

I'm working with WindowManager for showing popup (myView) with a Service (I can explain why but it's not the subject)
layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSPARENT);
layoutParams.gravity = Gravity.CENTER;
layoutParams.packageName = context.getPackageName();
layoutParams.buttonBrightness = 1f;
layoutParams.windowAnimations = R.style.DialogAnimation;
layoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
final WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
manager.addView(myView, layoutParams);
In my popup there is an EditText, when it request focus, automatically keyboard move up and the view do the same.
My problem is, when backButton is pressed, automatically keyBoard move down but not my view.
What can I do to make my view back down?

Android overlapping views when using WindowManager

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

Android right aligned LinearLayout strange animations on layout change

I have a right aligned linearlayout attached to a window (I am using a service)
LinearLayout ll = new LinearLayout(this);
llp = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE);
llp.gravity = Gravity.RIGHT;
windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
windowManager.addView(ll, llp);
It has two elements in it: an ImageView and a TextView.
LinearLayout.LayoutParams textParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, fixedHeight);
textView = new TextView(this);
ll.addView(textView, textParam);
LinearLayout.LayoutParams imageParam = new LinearLayout.LayoutParams(fixedWidth, fixedHeight);
imageView = new ImageView(this);
ll.addView(imageView, imageParam);
This all works as expected, and image is on the far right and a text snippet is to the left of the image. However after a set amount of time I hide the text snippet.
textView.setVisibility(View.GONE);
I would have thought doing so would have no effect on the imageView as the imageView is on the far right.
However it appears there is some sort of built in animation on layoutchanges which makes the imageview jump to the left most point of the linearlayout and animate back to its original position.
Does anyone know how to disable that animation? I have looked into it and thought something like this would do it:
ll.setLayoutTransition(null);
But it has no effect. I also found this suggestion:
LayoutTransition lt = new LayoutTransition();
lt.disableTransitionType(LayoutTransition.DISAPPEARING);
mContainerView.setLayoutTransition(lt);
That changed the animation actually making it a bit worse for my case.
If anyone has any information on how to disable all layoutchange animations or even any information on them it would be much appreciated.

DialogFragment Center Horizontal

I tried to make my dialog fill in the whole screen. Here's the code:
public void onStart() {
super.onStart();
AlertDialog dialog = (AlertDialog)getDialog();
WindowManager.LayoutParams params = getDialog().getWindow().getAttributes();
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setAttributes(params);
}
The problem is that the height still seems to wrap the content. The width however looks fine. This would be okay, but besides the fact that the height isn't filling the whole screen, the dialog now isn't horizontally centered anymore, but starts at the top edge of the screen.
I already tried params.gravity = Gravity.CENTER without success.
Any ideas on that?

Brightness Screen Filter

Does anyone have an idea how to implement an Brightness Screen Filter like the one here:
http://www.appbrain.com/app/screen-filter/com.haxor
I need a starting point and I can't figure out how to do it.
Just make a transparent full screen activity that lets touches pass through. To make touches pass through use the following Window flags before setting the contentView:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Window window = getWindow();
// Let touches go through to apps/activities underneath.
window.addFlags(FLAG_NOT_TOUCHABLE);
// Now set up content view
setContentView(R.layout.main);
}
For your main.xml layout file just use a full screen LinearLayout with a transparent background:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/background"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#33000000">
</LinearLayout>
Then to adjust the "brightness" just change the value of the background colour from your code somewhere:
findViewById(R.id.background).setBackgroundColor(0x66000000);
Get an instance of WindowManager.
WindowManager windowManager = (WindowManager) Class.forName("android.view.WindowManagerImpl").getMethod("getDefault", new Class[0]).invoke(null, new Object[0]);
Create a full screen layout xml(layout parameters set to fill_parent)
Set your view as not clickable, not focusable, not long clickable, etc so that touch is passed through to your app and the app can detect it.
view.setFocusable(false);
view.setClickable(false);
view.setKeepScreenOn(false);
view.setLongClickable(false);
view.setFocusableInTouchMode(false);
Create a layout parameter of type android.view.WindowManager.LayoutParams.
LayoutParams layoutParams = new LayoutParams();
Set layout parameter like height, width etc
layoutParams.height = LayoutParams.FILL_PARENT;
layoutParams.width = LayoutParams.FILL_PARENT;
layoutParams.flags = 280; // You can try LayoutParams.FLAG_FULLSCREEN too
layoutParams.format = PixelFormat.TRANSLUCENT; // You can try different formats
layoutParams.windowAnimations = android.R.style.Animation_Toast; // You can use only animations that the system to can access
layoutParams.type = LayoutParams.TYPE_SYSTEM_OVERLAY;
layoutParams.gravity = Gravity.BOTTOM;
layoutParams.x = 0;
layoutParams.y = 0;
layoutParams.verticalWeight = 1.0F;
layoutParams.horizontalWeight = 1.0F;
layoutParams.verticalMargin = 0.0F;
layoutParams.horizontalMargin = 0.0F;
Key step: You can set what percentage of brightness you need.
layoutParams.setBackgroundDrawable(getBackgroundDrawable(i));
private Drawable getBackgroundDrawable(int i) {
int j = 255 - (int) Math.round(255D * Math.exp(4D * ((double) i / 100D) - 4D));
return new ColorDrawable(Color.argb(j, 0, 0, 0));}
Finally add view to windowManager that you created earlier.
windowManager.addView(view, layoutParams);
Note: You need SYSTEM_ALERT_WINDOW permission to lay an overlay on the screen.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Have tested this and it works. Let me know if you get stuck.
Of course you can't use this is production code, but if you are playing around .. try this Undocumented hack
It uses :
private void setBrightness(int brightness) {
try {
IHardwareService hardware = IHardwareService.Stub.asInterface(
ServiceManager.getService("hardware"));
if (hardware != null) {
hardware.setScreenBacklight(brightness);
}
} catch (RemoteException doe) {
}
}
Remember that it uses this permission :
<uses-permission android:name="android.permission.HARDWARE_TEST"/>
You ca try this also:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.max_bright);
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 100 / 100.0f;
getWindow().setAttributes(lp);
}

Categories

Resources