辅助功能服务
1,创建服务类MyAccessibilityService继承AccessibilityService。import android.accessibilityservice.AccessibilityService;
public class MyAccessibilityService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
String packageName = event.getPackageName().toString();
String className = event.getClassName().toString();
Log.v(TAG, "包名:" + packageName + " 类名:" + className);
}
}
@Override
public void onInterrupt() {
}
}
2,创建服务的配置属性文件res/xml/service_config.xml.
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackVisual"
android:canRetrieveWindowContent="true"
android:accessibilityFlags="flagDefault" />
3,清单文件(AndroidManifest.xml)中配置
<service
android:name="com.example.server.MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/service_config" />
</service>
4,手动打开需要跳转到辅助页面。
// 跳转到辅助功能页面,用于开启或关闭,服务。
public static void jump(Context context) {
context.startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
}
5,判断当前应用的辅助功能服务是否开启
public static String packageNameAndclassName = "com.example.server/com.example.server.MyAccessibilityService";//格式:包名/类名
public static boolean isAccessibilitySettingsOn(Context context, String packageNameAndclassName) {
int accessibilityEnabled = 0;
try {
accessibilityEnabled = Settings.Secure.getInt(context.getContentResolver(), android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
if (accessibilityEnabled == 1) {
String services = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (services != null) {
return services.toLowerCase().contains(packageNameAndclassName.toLowerCase());
}
}
return false;
}
6,代码打开或关闭指定的服务。
public static String packageNameAndclassName = "com.example.server/com.example.server.MyAccessibilityService";//格式:包名/类名
// 需要权限
// <uses-permission android:name="android.permission.WRITE_SETTINGS" />
// <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
public static void openAccessibilitySettings(Context context, String packageNameAndclassName) {
String accessibilityStr = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (accessibilityStr.toLowerCase().contains(packageNameAndclassName.toLowerCase())) {
return;
}
if (TextUtils.isEmpty(accessibilityStr)) {
accessibilityStr = packageNameAndclassName;
} else {
accessibilityStr = accessibilityStr + ":" + packageNameAndclassName;
}
Settings.Secure.putString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, accessibilityStr);
Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, 1);
}
public static void closeAccessibilitySettings(Context context, String packageNameAndclassName) {
String accessibilityAllString = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (!TextUtils.isEmpty(accessibilityAllString) && accessibilityAllString.toLowerCase().contains(packageNameAndclassName.toLowerCase())) {
String retAccessibilitySeting = null;
if (TextUtils.equals(accessibilityAllString.toLowerCase(), packageNameAndclassName.toLowerCase())) {
retAccessibilitySeting = null;
} else {
int index = accessibilityAllString.toLowerCase().indexOf(packageNameAndclassName.toLowerCase());
if (index == 0) {
retAccessibilitySeting = accessibilityAllString.substring(packageNameAndclassName.length() + 1);
} else if (index + packageNameAndclassName.length() == accessibilityAllString.length()) {
retAccessibilitySeting = accessibilityAllString.substring(0, index - 1);
} else {
retAccessibilitySeting = accessibilityAllString.substring(0, index - 1)
+ accessibilityAllString.substring(index + packageNameAndclassName.length());
}
}
Settings.Secure.putString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, retAccessibilitySeting);
Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, TextUtils.isEmpty(retAccessibilitySeting) ? 0 : 1);
}
}
7,事件:
参考网址:https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityEvent.html
事件:
TYPE_VIEW_CLICKED//view点击
getEventType() - The type of the event.
getClassName() - The class name of the source.
getPackageName() - The package name of the source.
getSource() - The source info (for registered clients).
getEventTime() - The event time.
getText() - The text of the source's sub-tree.
isEnabled() - Whether the source is enabled.
isPassword() - Whether the source is password.
isChecked() - Whether the source is checked.
getContentDescription() - The content description of the source.
getScrollX() - The offset of the source left edge in pixels (without descendants of AdapterView).
getScrollY() - The offset of the source top edge in pixels (without descendants of AdapterView).
getFromIndex() - The zero based index of the first visible item of the source, inclusive (for descendants of AdapterView).
getToIndex() - The zero based index of the last visible item of the source, inclusive (for descendants of AdapterView).
getItemCount() - The total items of the source (for descendants of AdapterView).
TYPE_WINDOW_STATE_CHANGED//切换到新窗口。
getEventType() - The type of the event.
getClassName() - The class name of the source.
getPackageName() - The package name of the source.
getSource() - The source info (for registered clients).
getEventTime() - The event time.
getText() - The text of the source's sub-tree.
isEnabled() - Whether the source is enabled.
TYPE_WINDOW_CONTENT_CHANGED
getEventType() - The type of the event.
getContentChangeTypes() - The type of content changes.
getSource() - The source info (for registered clients).
getClassName() - The class name of the source.
getPackageName() - The package name of the source.
getEventTime() - The event time.
跑龙套的事件:
TYPE_WINDOWS_CHANGED
TYPE_VIEW_LONG_CLICKED//长点。
TYPE_VIEW_SELECTED//选择。
TYPE_VIEW_FOCUSED//获取焦点。
TYPE_VIEW_TEXT_CHANGED
TYPE_VIEW_TEXT_SELECTION_CHANGED
TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
TYPE_VIEW_SCROLLED
TYPE_NOTIFICATION_STATE_CHANGED
TYPE_VIEW_HOVER_ENTER
TYPE_VIEW_HOVER_EXIT
TYPE_TOUCH_INTERACTION_START//触摸交互开始。
getEventType() - The type of the event.
TYPE_TOUCH_INTERACTION_END
getEventType() - The type of the event.
TYPE_TOUCH_EXPLORATION_GESTURE_START
1 1 TYPE_VIEW_CLICKED//view点击
32 20 TYPE_WINDOW_STATE_CHANGED//一般用的窗口状态监听。
2048 800 TYPE_WINDOW_CONTENT_CHANGED//改变一个窗口的内容的事件
8 8 TYPE_VIEW_FOCUSED//view获取焦点
64 40 TYPE_NOTIFICATION_STATE_CHANGED//通知状态改变
4096 1000 TYPE_VIEW_SCROLLED//滚动view。