Touch event.getAction does not work under service class in android studio
Asked Answered
S

1

1

I developed an App to collect touch events under the foreground service class. The app has a main activity to input user's information (e.g., name and age). Then a foreground service starts to collect touch events, and a notification is launched to inform the user that the service is running.

This is the main activity code

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
switch (item.getItemId()) {
    case R.id.run_catch:
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            intent = new Intent(this, SensorService.class);
            this.startForegroundService(intent);
            setStartPreferences(true);
            isStart = true;
        } else {
            intent = new Intent(this, SensorService.class);
            this.startService(intent);
            setStartPreferences(true);
            isStart = true;
        }


        break;
    case R.id.stop_catch:
        intent = new Intent(getApplicationContext(), SensorService.class);
        stopService(intent);

        setStartPreferences(false);
        isStart = false;
        break;
}
return super.onOptionsItemSelected(item);
 }

The problem is that the Touch event can not be gathered under the service class. I mean that the event.getAction() function does not work not inside nor outside the app to collect the touch events using the following options: MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP and MotionEvent.ACTION_OUTSIDE. However, I can collect the touch time in milliseconds using the function gettime_in_ms() when tapping either inside or outside the app.

This is the service class code:

public class SensorService extends Service implements SensorEventListener, LocationListener, View.OnTouchListener{
  //Touch
  private WindowManager windowManager;
  private LinearLayout touchLayout;
   @Nullable
   @Override
   public IBinder onBind(Intent intent) {
   return null;
    }

    @Override
      public void onCreate() {
      super.onCreate();
     try {
       initTouch();
        } catch (Exception e) {
         e.printStackTrace();
        }
        notification();
         }
public void initTouch() {
    touchLayout = new LinearLayout(this);
    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
    lp.width = WindowManager.LayoutParams.MATCH_PARENT;
    lp.height =WindowManager.LayoutParams.MATCH_PARENT;
    touchLayout.setLayoutParams(lp);
    touchLayout.setOnTouchListener(SensorService.this);
    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
    }
    else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O){
        LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
    }


    // set layout parameter of window manager
    WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(
            0,
            0,
            LAYOUT_FLAG,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
           |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);
    mParams.gravity = Gravity.LEFT | Gravity.TOP;

    windowManager.addView(touchLayout, mParams);
    }
 @Override
 public boolean onTouch(View view, MotionEvent motionEvent) {
   Toast.makeText(this, "Touch Event occur"+ "\n"+ gettime_in_ms() + "\n", 
   Toast.LENGTH_SHORT).show();

int action = motionEvent.getAction();

    switch(action) {
        case (MotionEvent.ACTION_DOWN) :
            Log.d("DEBUG_TAG","Action was DOWN");
            return true;
        case (MotionEvent.ACTION_MOVE) :
            Log.d("DEBUG_TAG","Action was MOVE");
            return true;
        case (MotionEvent.ACTION_UP) :
            Log.d("DEBUG_TAG","Action was UP");
            return true;
        case (MotionEvent.ACTION_CANCEL) :
            Log.d("DEBUG_TAG","Action was CANCEL");
            return true;
        case (MotionEvent.ACTION_OUTSIDE) :
            Log.d("DEBUG_TAG","Movement occurred outside bounds " +
                    "of current screen element");
            return true;
        default :
            break;
    }
   return true;
   }

This code always give (Movement occurred outside bounds of current screen element) as an output. I need to get the times in milliseconds of the down, move, and up actions when the user taps inside and outside the app (I mean when interacting with other apps on the phone).

Is this possible under the service class? If yes could anyone gives example code, useful links or information?

Sartain answered 22/12, 2020 at 8:38 Comment(1)
I think you can't do this because service is not a view. Only Views can trigger a touch event. or maybe this works https://mcmap.net/q/102692/-how-can-a-service-listen-for-touch-gestures-eventsGoetz
C
0

You can use Gesture Detector and apply WindowManager.LayoutParams.TYPE_SYSTEM_ALERT in WindowsManager Check out this link

Caniff answered 11/11, 2022 at 8:6 Comment(1)
TYPE_SYSTEM_ALERT does not support the overlay function as TYPE_APPLICATION_OVERLAY.Sartain

© 2022 - 2024 — McMap. All rights reserved.