Type_System_Overlay in Ics

TYPE_SYSTEM_OVERLAY in ICS

Everything you describe is true. It is presumably to tighten up security, as the former behavior was the source of tapjacking attacks. I wrote a blog post recently about this change.

Any idea's?

Don't use either of them.

TYPE_SYSTEM_OVERLAY detect touches in ICS

It seems this is just the case, as this post highlights. This is generally a bad idea, see the documentation:

These windows must not take input focus, or they will interfere with the keyguard.

I haven't actually tested those overlays on Android 4.0 ICS but other apps like SwipePad seem to do this just fine. The only concern I am aware of is related to performance, such overlays often take a hefty toll on the device. If you want to accurately detect touch input and the overlay does not have to be above the lock screen, try TYPE_SYSTEM_ALERT. Another post on SO seems to have chosen that type as well.

TYPE_SYSTEM_OVERLAY in Android 4 ICS

I see that TYPE_SYSTEM_ALERT still works on ICS and I need to come up with a solution using this flag.

Full screen overlay in ICS

I know only solution with replacing TYPE_SYSTEM_ALERT to TYPE_SYSTEM_OVERLAY. But in this way your window will not receive touch events.

Could not get Touch event for TYPE_SYSTEM_OVERLAY

To hide the view you need to call mWindowManager.removeView(mOverlay);

private RelativeLayout mOverlay;
private WindowManager mWindowManager;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mOverlay = (RelativeLayout) inflater
.inflate(R.layout.phasechange, null);

mWindowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
mWindowManager.addView(mOverlay, params);
Button b = (Button) mOverlay.findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mWindowManager.removeView(mOverlay);
}
});

}

Creating a system overlay window (always on top)

This might be a stupid solution. But it works. If you can improve it, please let me know.

OnCreate of your Service: I have used WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH flag. This is the only change in service.

@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. So, you need to rectify in your event handler.

In your ViewGroup touch event

@Override
public boolean onTouchEvent(MotionEvent event) {

// ATTENTION: GET THE X,Y OF EVENT FROM THE PARAMETER
// THEN CHECK IF THAT IS INSIDE YOUR DESIRED AREA

Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
return true;
}

Also you may need to add this permission to your manifest:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />


Related Topics



Leave a reply



Submit