我目前正在尝试开发一种可以捕获用于研究的全局触摸手势的应用程序。如果可能的话,我希望在没有手机的情况下实现这一目标,并且由于覆盖不能再用于此了,我试图通过触摸探索的可访问性服务来实现它。
目前,我能够获取包含手势/触摸信息的AccessibilityEvents,如果识别,则可以获取已执行的一般滑动类型。
我怀疑AccessibilityEvents根本不包含更多特定数据,但我很想知道是否有人有解决方案,或者可以确认不可能。
以下是该服务的源代码:
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";
}
}
以下是输出的片段:
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