After some more research and testing I've managed to rise with a solution.
What I did was to create a background service in which I get an instance of the WindowManager and add a zero sized view that get's notified of user
touches outside of it... but as the view has zero size it can get called every time.
For that we may check https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html
The InactivityService.java class detects every time the user taps the screen and write it to the preferences so it can be displayed or employed later in other components of the app.
It's valid to notice that we can broadcast the time, or pass it to our app object or whatever other solution suits or needs.
/**
* Detects user taps on screen (user interaction).
*
* @author Junior Buckeridge A.
*
*/
public class InactivityService extends Service {
protected static final String LOG_TAG = InactivityService.class.getSimpleName();
private boolean isAdded = false;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(!isAdded){
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
0, 0, 0, 0,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
View view = new View(this);
view.setOnTouchListener(new OnTouchListener() {
@SuppressLint("DefaultLocale")
@Override
public boolean onTouch(View v, MotionEvent event) {
GregorianCalendar calendar = new GregorianCalendar();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(InactivityService.this);
String log = prefs.getString(LOG_KEY, "");
log = String.format("User interaction detected at: %02d:%02d:%02d \n%s",
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
calendar.get(Calendar.SECOND),
log);
prefs.edit().putString(LOG_KEY, log).commit();
return false;
}
});
wm.addView(view, params);
}
return START_STICKY;
}
}
We should add the following permission to the manifest:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Also valid to mention that this method, combined with getting the running tasks with ActivityManager is a very effective way to determine if the user is interacting with the handset.