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?
view
. OnlyViews
can trigger a touch event. or maybe this works https://mcmap.net/q/102692/-how-can-a-service-listen-for-touch-gestures-events – Goetz