9

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;
    }
}
Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
Henry
  • 157
  • 1
  • 3
  • 12

1 Answers1

1

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.

Community
  • 1
  • 1
user1723095
  • 1,181
  • 1
  • 13
  • 24
  • 1
    Now the onTouch method return false, but while the service is running, I still can't press and open any app in my home screen. I have read the link you posted, maybe ontouch() method and onTouchEvent method are different? I implemented ontouch() method within my service class, the service class implemented onTouchListener. – Henry May 06 '15 at 12:32
  • In the tutorial you follow width is set to 30px and you set it to: WindowManager.LayoutParams.MATCH_PARENT That's why it covers whole area and you can't start any app. Try setting background color to your layout so you'll see how big it is. – user1723095 May 06 '15 at 12:52
  • I am making an app that creates a service that will detect any touch on the screen, so I set the width and height to cover the whole screen. Now the problem is that the layout created by the service which is used to detect screen touch consume the touch event when I am pressing on other app icon in the home screen. As a result, I can't open other app and I cant do anything when the service is running. – Henry May 06 '15 at 13:12
  • I'm not sure but I think what is going on in your case is that although you ignore touch event in layout (by returning false) touch goes to it's parent (view) which consumes event anyway. Maybe instead of covering whole screen you could shrink this area and use FLAG_WATCH_OUTSIDE_TOUCH – user1723095 May 06 '15 at 13:50
  • I see. and is there a way I can get to its parent and prevent consuming the event there? – Henry May 06 '15 at 22:11
  • I don't think you can prevent consuming the event in parent. Alternatively you can try touchLayout.setClickable(false) but I haven't tested if it will work. Anyway if your layout would be very small 30x30 px or maybe even 1x1 px and you would use FLAG_WATCH_OUTSIDE_TOUCH (maybe with combination of FLAG_NOT_TOUCH_MODAL) then maybe you could intercept touch events without affecting user actions. Another workaround I could think of would be disabling touchLayout in event handler, simulating intercepted action (touchLayout would be disabled so it won't consume) and then enabling touchLayout again. – user1723095 May 07 '15 at 07:27
  • Please, I have the same issue where I need to collect touch data from anywhere in my phone while a background service is running. Can you help me with this? please check my question here: https://stackoverflow.com/questions/65405516/touch-event-getaction-does-not-work-under-service-class-in-android-studio?noredirect=1#comment115787432_65405516 – Mohsen Ali Jan 04 '21 at 05:40