I am currently trying to develop an application that can capture global touch gestures to be used in research. If possible I would like to achieve this without rooting the phone, and since overlays can not be used for this anymore i'm trying to achieve it through an accessibility service with touch exploration.
Currently I am able to get AccessibilityEvents containing information that there has been a gesture/touch and if recognized, the general type of swipe that has been performed.
I suspect that AccessibilityEvents simply do not contain more specific data, but I would love to know if anyone has a solution to this or can confirm that it is not possible.
Here is the sourcecode for the service:
package com.theia.servicetest;
import android.accessibilityservice.AccessibilityService;
import android.util.Log;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityEvent;
/**
* Accessibility Service test
*/
public class accessibilityService extends AccessibilityService {
@Override
public void onCreate() {
Log.v("THEIA", "Service Created");
}
@Override
protected boolean onGesture(int gestureId) {
Log.v("THEIA", String.format("onGesture: [type] %s", gIdToString(gestureId)));
return false;
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.v("THEIA", String.format(
"onAccessibilityEvent: [type] %s [class] %s [package] %s [time] %s",
idToText(event), event.getClassName(), event.getPackageName(), event.getEventTime()));
if(idToText(event)=="TYPE_VIEW_HOVER_ENTER" || idToText(event)=="TYPE_VIEW_HOVER_EXIT") {
Log.v("THEIA", String.format("onHoverEvent: [scrollX] %s [scrollY] %s",
event.getScrollX(), event.getScrollY()));
}
}
@Override
public void onInterrupt() {
Log.v("THEIA", "INTERRUPTED");
}
@Override
protected void onServiceConnected() {
super.onServiceConnected();
Log.v("THEIA", "AccessibilityService allowed");
}
/**
* Converts an ID returned by AccessibilityEvent.getEventType()
* to a representative String
*/
private String idToText(AccessibilityEvent event) {
switch (event.getEventType()) {
case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START:
return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:
return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
case AccessibilityEvent.TYPE_TOUCH_INTERACTION_START:
return "TYPE_TOUCH_INTERACTION_START";
case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
return "TYPE_TOUCH_INTERACTION_END";
case AccessibilityEvent.TYPE_GESTURE_DETECTION_START:
return "TYPE_GESTURE_DETECTION_START";
case AccessibilityEvent.TYPE_GESTURE_DETECTION_END:
return "TYPE_GESTURE_DETECTION_END";
case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
return "TYPE_VIEW_HOVER_ENTER";
case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
return "TYPE_VIEW_HOVER_EXIT";
case AccessibilityEvent.TYPE_VIEW_SCROLLED:
return "TYPE_VIEW_SCROLLED";
case AccessibilityEvent.TYPE_VIEW_CLICKED:
return "TYPE_VIEW_CLICKED";
case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED:
return "TYPE_VIEW_LONG_CLICKED";
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
return "TYPE_VIEW_FOCUSED";
case AccessibilityEvent.TYPE_VIEW_SELECTED:
return "TYPE_VIEW_SELECTED";
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
return "TYPE_VIEW_ACCESSIBILITY_FOCUSED";
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED";
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
return "TYPE_WINDOW_STATE_CHANGED";
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
return "TYPE_NOTIFICATION_STATE_CHANGED";
case AccessibilityEvent.TYPE_ANNOUNCEMENT:
return "TYPE_ANNOUNCEMENT";
case AccessibilityEvent.TYPE_WINDOWS_CHANGED:
return "TYPE_WINDOWS_CHANGED";
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
return "TYPE_WINDOW_CONTENT_CHANGED";
case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
return "TYPE_VIEW_TEXT_CHANGED";
case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED:
return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
case AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
return "TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY";
}
return "Unknown";
}
/**
* Converts gestureID to a representative String
* @param gID
* @return
*/
private String gIdToString(int gID) {
switch(gID) {
case 1: return "GESTURE_SWIPE_UP";
case 2: return "GESTURE_SWIPE_DOWN";
case 3: return "GESTURE_SWIPE_LEFT";
case 4: return "GESTURE_SWIPE_RIGHT";
case 5: return "GESTURE_SWIPE_LEFT_AND_RIGHT";
case 6: return "GESTURE_SWIPE_RIGHT_AND_LEFT";
case 7: return "GESTURE_SWIPE_UP_AND_DOWN";
case 8: return "GESTURE_SWIPE_DOWN_AND_UP";
case 9: return "GESTURE_SWIPE_LEFT_AND_UP";
case 10: return "GESTURE_SWIPE_LEFT_AND_DOWN";
case 11: return "GESTURE_SWIPE_RIGHT_AND_UP";
case 12: return "GESTURE_SWIPE_RIGHT_AND_DOWN";
case 13: return "GESTURE_SWIPE_UP_AND_LEFT";
case 14: return "GESTURE_SWIPE_UP_AND_RIGHT";
case 15: return "GESTURE_SWIPE_DOWN_AND_LEFT";
case 16: return "GESTURE_SWIPE_DOWN_AND_RIGHT";
}
return "UNKNOWN";
}
}
And here is a snippet of the output:
03-24 19:11:06.350 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_TOUCH_INTERACTION_START [class] null [package] null [time] 618934
03-24 19:11:06.483 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_TOUCH_EXPLORATION_GESTURE_START [class] null [package] null [time] 619067
03-24 19:11:06.487 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_VIEW_HOVER_ENTER [class] android.widget.ListView [package] com.android.settings [time] 619068
03-24 19:11:06.487 3767-3767/com.theia.servicetest V/THEIA﹕ onHoverEvent: [scrollX] -1 [scrollY] -1
03-24 19:11:06.806 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_VIEW_HOVER_ENTER [class] android.widget.TextView [package] com.android.settings [time] 619390
03-24 19:11:06.806 3767-3767/com.theia.servicetest V/THEIA﹕ onHoverEvent: [scrollX] -1 [scrollY] -1
03-24 19:11:06.909 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_VIEW_HOVER_EXIT [class] android.widget.TextView [package] com.android.settings [time] 619493
03-24 19:11:06.909 3767-3767/com.theia.servicetest V/THEIA﹕ onHoverEvent: [scrollX] -1 [scrollY] -1
03-24 19:11:07.026 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_VIEW_HOVER_EXIT [class] android.widget.ListView [package] com.android.settings [time] 619609
03-24 19:11:07.026 3767-3767/com.theia.servicetest V/THEIA﹕ onHoverEvent: [scrollX] -1 [scrollY] -1
03-24 19:11:07.028 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_TOUCH_EXPLORATION_GESTURE_END [class] null [package] null [time] 619610
03-24 19:11:07.028 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_TOUCH_INTERACTION_END [class] null [package] null [time] 619610
03-24 19:11:13.392 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_TOUCH_INTERACTION_START [class] null [package] null [time] 625976
03-24 19:11:13.493 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_GESTURE_DETECTION_START [class] null [package] null [time] 626077
03-24 19:11:13.510 3767-3767/com.theia.servicetest V/THEIA﹕ onGesture: [type] GESTURE_SWIPE_RIGHT
03-24 19:11:13.610 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_GESTURE_DETECTION_END [class] null [package] null [time] 626194
03-24 19:11:13.610 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_TOUCH_INTERACTION_END [class] null [package] null [time] 626194
03-24 19:11:15.777 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_TOUCH_INTERACTION_START [class] null [package] null [time] 628361
03-24 19:11:15.928 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_GESTURE_DETECTION_START [class] null [package] null [time] 628512
03-24 19:11:16.234 3767-3767/com.theia.servicetest V/THEIA﹕ onGesture: [type] GESTURE_SWIPE_UP_AND_RIGHT
03-24 19:11:16.334 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_GESTURE_DETECTION_END [class] null [package] null [time] 628918
03-24 19:11:16.334 3767-3767/com.theia.servicetest V/THEIA﹕ onAccessibilityEvent: [type] TYPE_TOUCH_INTERACTION_END [class] null [package] null [time] 628918