I'm trying to recover all touch events that occur anywhere on a mobile device (i.e. not only restricted to one activity)
I have a service:
public class OverlayExampleService extends Service implements View.OnTouchListener {
private String TAG = this.getClass().getSimpleName();
// window manager
private WindowManager mWindowManager;
// linear layout will use to detect touch event
private LinearLayout touchLayout;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
// create linear layout
touchLayout = new LinearLayout(this);
// set layout width 30 px and height is equal to full screen
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(30, WindowManager.LayoutParams.MATCH_PARENT);
touchLayout.setLayoutParams(lp);
// set color if you want layout visible on screen
// touchLayout.setBackgroundColor(Color.CYAN);
// set on touch listener
touchLayout.setOnTouchListener(this);
// fetch window manager object
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
// set layout parameter of window manager
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT, // width of layout 30 px
WindowManager.LayoutParams.MATCH_PARENT, // height is equal to full screen
WindowManager.LayoutParams.TYPE_PHONE, // Type Phone, These are non-application windows providing user interaction with the phone (in particular incoming calls).
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, // this window won't ever get key input focus
PixelFormat.TRANSLUCENT);
mParams.gravity = Gravity.LEFT | Gravity.TOP;
Log.e(TAG, "add View");
mWindowManager.addView(touchLayout, mParams);
}
@Override
public void onDestroy() {
if(mWindowManager != null) {
if(touchLayout != null) mWindowManager.removeView(touchLayout);
}
super.onDestroy();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP)
Log.e(TAG, "Action :" + event.getAction() + "\t X :" + event.getRawX() + "\t Y :"+ event.getRawY());
return false;
}
}
And an activity that starts it:
public class MainActivity extends Activity {
Intent globalService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
globalService = new Intent(this, OverlayExampleService.class);
}
public void buttonClicked(View v){
if(v.getTag() == null){
startService(globalService);
v.setTag("on");
Toast.makeText(this, "Start Service", Toast.LENGTH_SHORT).show();
}
else{
stopService(globalService);
v.setTag(null);
Toast.makeText(this, "Stop Service", Toast.LENGTH_SHORT).show();
}
}
}
Here is the activity's layout xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Start Touch Detection"
android:onClick="buttonClicked" />
</RelativeLayout>
This works, and I can successfully recover Touch X/Y locations but once that is done the touch event is consumed. I would like it to continue onto the activity/display in the backgorund (i.e. Home screen, other apps etc.).
I have tried returning false in the onTouch function but that does not seem to work.
I also know about this issue: Android 4.2 ACTION_OUTSIDE MotionEvent X and Y return 0 outside of own application and that is why I have my windowManger parameters spanning the whole screen (MATCH_PARENT parameters).
So, is there a way to achieve this?