I am working on a project on android studio. I need to detect whether the screen is touched or not in a background service (and pop up a message for that). But, I have problem detecting whether the screen is touched or not in a background service without affecting user using the smartphone.
When I say "detect in background", I mean the effect of the app will not interfere with what the user is doing on the screen. My progress below should explain what i mean here:
I made an app that will detect whether the user touch the screen in background by implementing onTouchListener in android and use a layout for that onTouchListener. I did this by following the instruction in the website "http://kpbird.blogspot.com.au/2013/03/android-detect-global-touch-event.html" and I made some changes to the layout to cover the whole screen so it can detect the whole screen.
But, after I ran my app which created the service that keeps detecting screen touch, every time when the user touch the screen, that touch is absorbed by my service (the layout), so the user can't properly use their phone anymore (like pressing an icon to start other apps). This is because the layout covers the whole screen and blocking any touch info to the icon underneath it (the layout detect screen touch), so the icon don't know there is a touch and hence will not react to user. But I want my app and service to allow the user to use their phone normally.
I heard that the service in android is designed to not interact with user (i.e. screen touches) and work in background, but I want to know if there is a way around this.
Below is the code of my service:
public class GlobalTouchService extends Service implements 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
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, 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 is equal to full screen
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, // this window won't ever get key input focus
PixelFormat.TRANSLUCENT);
mParams.gravity = Gravity.LEFT | Gravity.TOP;
Log.i(TAG, "add View");
mWindowManager.addView(touchLayout, mParams);
}
@Override
public void onDestroy() {
if(mWindowManager != null) {
if(touchLayout != null) mWindowManager.removeView(touchLayout);
}
super.onDestroy();
}
public void showAlert(View view) {
AlertDialog.Builder myAlertBuilder = new AlertDialog.Builder(this);
myAlertBuilder.setMessage(getString(R.string.alertMessage))
.setTitle(getString(R.string.alertTitle))
.setPositiveButton(getString(R.string.alertPositiveChoice), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setNegativeButton(getString(R.string.alertNegativeChoice), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
onDestroy();
}
});
AlertDialog myAlert = myAlertBuilder.create();
myAlert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
myAlert.show();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
//if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP)
// Log.i(TAG, "Action :" + event.getAction() + "\t X :" + event.getRawX() + "\t Y :" + event.getRawY());
////////////////////
View myView = null;
//showAlert(myView);
///////////////////////
return false;
}
}
You have onTouch method there. Just return false and touch won't be absorbed by your app.
Please also check this: https://stackoverflow.com/a/6384443/1723095
Edit: It's probably not what you want but if you have rooted device you can do something like that:
adb shell getevent dev/input/event1
In my case event1 is responsible for touch events but it can differ.