0
点赞
收藏
分享

微信扫一扫

安卓无障碍笔记-AccessibilityService


项目demo地址,demo_accessibility目录下;
​​​ https://gitee.com/catface7/catface_app​​

核心服务lib模块

安卓无障碍笔记-AccessibilityService_List

  • res>xml>accessibility_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="feedbackGeneric"
android:accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows|flagRequestFilterKeyEvents"
android:canPerformGestures="true"
android:canRequestFilterKeyEvents="true"
android:canRetrieveWindowContent="true"
android:description="@string/accessibility_description"
android:notificationTimeout="100" />

  • res>values>strings.xml

<resources>
<string name="accessibility_description">辅助功能测试</string>
</resources>

  • AndroidManifest.xml中声明无障碍服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cc.catface.accessibility">

<application>
<service
android:name=".ProAccessibilityService"
android:enabled="true"
android:exported="true"
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/accessibility_config" />
</service>
</application>
</manifest>

  • 服务启动帮助类AccessibilitySettingOpenHelper

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;

import java.util.List;

public class AccessibilitySettingOpenHelper {

//跳转到开启无障碍设置页面
public static void jumpToSettingPage(Context context) {
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}

//判断自定义辅助功能服务是否开启
public static boolean isAccessibilitySettingsOn(Context context, String className) {
if (context == null) return false;
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (activityManager == null) return false;
//判断当前无障碍服务是否在运行服务列表中
List<ActivityManager.RunningServiceInfo> runningServices = activityManager.getRunningServices(100);
runningServices.size();
for (int i = 0; i < runningServices.size(); i++) {
ComponentName service = runningServices.get(i).service;
if (service.getClassName().equals(className)) {
return true;
}
}
return false;
}
}

  • 核心服务类ProAccessibilityService,包含根据id,文本内容,描述内容查找控件,模拟控件点击,绝对位置点击等功能;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.annotation.SuppressLint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
* 无障碍
* rootNode.findAccessibilityNodeInfosByViewId(id): 根据详细id查找控件
* rootNode.findAccessibilityNodeInfosByText(text): 根据文本内容查找控件
*/
public class ProAccessibilityService extends AccessibilityService {
private static final String TAG = "ProAccessibilityService";

private static ProAccessibilityService instance;

public static ProAccessibilityService getInstance() {
return instance;
}

//仅根据具体id/文本内容/描述查找控件|全开
private boolean findByIdEnabled, findByTextEnabled, findByDescEnabled, findByAllEnabled;
private int textMatchType = 0, descMatchType = 0;//0完全匹配1部分匹配2开头匹配3结尾匹配
private FindByIdCallback findByIdCallback;
private FindByTextCallback findByTextCallback;
private FindByDescCallback findByDescCallback;
private int[] clickId, clickText, clickDesc;//[0,0,1,1000](p1:0开启点击1关闭点击|p2:点击第几个控件|p3:每次点击前延时)
private CountDownTimer idTimer, textTimer, descTimer;


public void setClickId(int[] clickId) {
releaseAllTimer();
this.clickId = clickId;
}

public void setClickText(int[] clickText) {
releaseAllTimer();
this.clickText = clickText;
}

public void setClickDesc(int[] clickDesc) {
releaseAllTimer();
if (originNodeByDesc != null) originNodeByDesc.clear();
this.clickDesc = clickDesc;
}

public interface FindByIdCallback {
//原始节点集合;封装的节点集合
void byIdResult(List<AccessibilityNodeInfo> originNodes, List<NodeInfo> nodeInfos);
}

public interface FindByTextCallback {
//原始节点集合;封装的节点集合
void byTextResult(List<AccessibilityNodeInfo> originNodes, List<NodeInfo> nodeInfos);
}

public interface FindByDescCallback {
//原始节点集合;封装的节点集合
void byDescResult(List<AccessibilityNodeInfo> originNodes, List<NodeInfo> nodeInfos);
}

//id/文本内容/描述
private String id, text, desc;

public void setFindByAllEnabled() {
this.findByIdEnabled = true;
this.findByTextEnabled = true;
this.findByDescEnabled = true;
}

public void setFindByIdEnabled(FindByIdCallback callback) {
this.findByIdEnabled = true;
this.findByTextEnabled = false;
this.findByDescEnabled = false;
this.findByIdCallback = callback;
}

public void setFindByTextEnabled(FindByTextCallback callback) {
this.findByIdEnabled = false;
this.findByTextEnabled = true;
this.findByDescEnabled = false;
this.findByTextCallback = callback;
}

public void setFindByDescEnabled(FindByDescCallback callback) {
this.findByIdEnabled = false;
this.findByTextEnabled = false;
this.findByDescEnabled = true;
this.findByDescCallback = callback;
}

public void setId(String id) {
this.id = id;
}

public void setTextAndFilterType(String text, int type) {
this.text = text;
this.textMatchType = type;
}

public void setDescAndFilterType(String desc, int type) {
this.desc = desc;
this.descMatchType = type;
}


@Override//服务初始化连接
protected void onServiceConnected() {
super.onServiceConnected();
instance = this;
}

//原始节点信息转换目标节点信息
private List<NodeInfo> getTransNodes(List<AccessibilityNodeInfo> originNodes) {
List<NodeInfo> nodeInfos = new ArrayList<>();
for (AccessibilityNodeInfo n : originNodes) {
if (n.getText() == null) return new ArrayList<>();
NodeInfo info = new NodeInfo();
info.setViewIdResourceName(n.getViewIdResourceName());
info.setText(n.getText());
info.setContentDescription(n.getContentDescription());
info.setClassName(n.getClassName());
info.setPackageName(n.getPackageName());
info.setChildCount(n.getChildCount());
Rect rectInScreen = new Rect();
n.getBoundsInScreen(rectInScreen);
info.setBoundsInScreen(new int[]{rectInScreen.left, rectInScreen.top, rectInScreen.right, rectInScreen.bottom});
Rect rectInParent = new Rect();
n.getBoundsInParent(rectInParent);
info.setBoundsInParent(new int[]{rectInParent.left, rectInParent.top, rectInParent.right, rectInParent.bottom});
info.setClickable(n.isClickable());
nodeInfos.add(info);
}
return nodeInfos;
}

private List<AccessibilityNodeInfo> originNodeByDesc;

@SuppressLint("NewApi")
private void iteratorNode(AccessibilityNodeInfo rootNode) {
if (rootNode.getChildCount() != 0) {
for (int i = 0; i < rootNode.getChildCount(); i++) {
AccessibilityNodeInfo child = rootNode.getChild(i);
if (child.getChildCount() != 0) {
iteratorNode(child);
}
originNodeByDesc.add(child);
}
}
}

/*显示节点信息*/
private void showNodesInfo(String byWhat, List<AccessibilityNodeInfo> nodes) {
if (nodes == null || nodes.size() < 1) return;
int size = nodes.size();
for (int i = 0; i < nodes.size(); i++) {
AccessibilityNodeInfo child = nodes.get(i);
TLog.d(TAG, "===通过" + byWhat + "查找的节点结果, 第" + (i + 1) + "/" + size + "个", "id:" + child.getViewIdResourceName() + ", 类:" + child.getClassName() + ", 文本:" + child.getText() + ", 描述:" + child.getContentDescription());
}
}

private List<AccessibilityNodeInfo> originNodesByText;
private AccessibilityNodeInfo mClickNodeById;
private AccessibilityNodeInfo mClickNodeByText;
private AccessibilityNodeInfo mClickNodeByDesc;

@SuppressLint("NewApi")
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event == null) return;
//TLog.d(getClass().getSimpleName(), "=>进入无障碍核心回调onAccessibilityEvent(), packageName:" + event.getPackageName() + ", eventType:" + event.getEventType() + ", idTimer:" + idTimer + ", textTimer:" + textTimer + ", descTimer:" + descTimer);
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
if (rootNode == null) return;

//根据id查找
if (this.findByIdEnabled && this.id != null && !TextUtils.isEmpty(this.id) && this.findByIdCallback != null) {
TLog.d(TAG, "====================>开始通过id[" + id + "]&clickId[" + Arrays.toString(clickId) + "]查找节点");
final List<AccessibilityNodeInfo> originNodesById = rootNode.findAccessibilityNodeInfosByViewId(this.id);
showNodesInfo("id", originNodesById);//打印结果
this.findByIdCallback.byIdResult(originNodesById, getTransNodes(originNodesById));
//点击事件
if (this.clickId != null && this.clickId.length == 3 && this.clickId[0] == 0 && this.clickId[1] < originNodesById.size()) {
int clickNodeIndex = this.clickId[1];//第几个控件
int intervalMillis = this.clickId[2];//延时(ms)
mClickNodeById = originNodesById.get(clickNodeIndex);
if (idTimer == null) {
idTimer = new CountDownTimer(Integer.MAX_VALUE, intervalMillis) {
@Override
public void onTick(long l) {
performClick(mClickNodeById);
}

@Override
public void onFinish() {}
};
idTimer.start();
}
}
}
//根据text查找
if (this.findByTextEnabled && this.text != null && !TextUtils.isEmpty(this.text) && this.findByTextCallback != null) {
TLog.d(TAG, "====================>开始通过text[" + text + "]&clickText[" + Arrays.toString(clickText) + "]查找节点");
originNodesByText = rootNode.findAccessibilityNodeInfosByText(this.text);//根据文本内容查找控件
//根据文本内容匹配规则过滤[0完全匹配1部分匹配2开头匹配3结尾匹配]
if (originNodesByText == null || originNodesByText.size() < 1) {
this.findByTextCallback.byTextResult(new ArrayList<>(), new ArrayList<>());
} else {
originNodesByText = originNodesByText.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getText() != null).collect(Collectors.toList());
if (this.textMatchType == 0) {
originNodesByText = originNodesByText.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getText().toString().equals(this.text)).collect(Collectors.toList());
} else if (this.textMatchType == 1) {
originNodesByText = originNodesByText.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getText().toString().contains(this.text)).collect(Collectors.toList());
} else if (this.textMatchType == 2) {
originNodesByText = originNodesByText.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getText().toString().startsWith(this.text)).collect(Collectors.toList());
} else if (this.textMatchType == 3) {
originNodesByText = originNodesByText.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getText().toString().endsWith(this.text)).collect(Collectors.toList());
}
showNodesInfo("text", originNodesByText);//打印结果
this.findByTextCallback.byTextResult(originNodesByText, getTransNodes(originNodesByText));
}
//点击事件
if (this.clickText != null && this.clickText.length == 3 && this.clickText[0] == 0 && this.clickText[1] < originNodesByText.size()) {
int clickNodeIndex = this.clickText[1];//第几个控件
int intervalMillis = this.clickText[2];//延时(ms)
//判断这个控件是否可点
mClickNodeByText = originNodesByText.get(clickNodeIndex);
if (textTimer == null) {
textTimer = new CountDownTimer(Integer.MAX_VALUE, intervalMillis) {
@Override
public void onTick(long l) {
performClick(mClickNodeByText);
}

@Override
public void onFinish() {}
};
textTimer.start();
}
}
}
if (this.findByDescEnabled && this.desc != null && !TextUtils.isEmpty(this.desc) && this.findByDescCallback != null) {
TLog.d(getClass().getSimpleName(), "====================>开始通过desc[" + desc + "]&clickDesc[" + Arrays.toString(clickDesc) + "]查找节点");
//遍历所有控件
originNodeByDesc = new ArrayList<>();
iteratorNode(rootNode);
//打印遍历的页面所有节点信息
showNodesInfo("desc[原始]", originNodeByDesc);
if (originNodeByDesc == null || originNodeByDesc.size() < 1) {
this.findByDescCallback.byDescResult(new ArrayList<>(), new ArrayList<>());
} else {
originNodeByDesc = originNodeByDesc.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getContentDescription() != null).collect(Collectors.toList());
if (this.descMatchType == 0) {
originNodeByDesc = originNodeByDesc.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getContentDescription().toString().equals(this.desc)).collect(Collectors.toList());
} else if (this.descMatchType == 1) {
originNodeByDesc = originNodeByDesc.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getContentDescription().toString().contains(this.desc)).collect(Collectors.toList());
} else if (this.descMatchType == 2) {
originNodeByDesc = originNodeByDesc.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getContentDescription().toString().startsWith(this.desc)).collect(Collectors.toList());
} else if (this.descMatchType == 3) {
originNodeByDesc = originNodeByDesc.stream().filter(accessibilityNodeInfo -> accessibilityNodeInfo.getContentDescription().toString().endsWith(this.desc)).collect(Collectors.toList());
}
showNodesInfo("desc[过滤]", originNodeByDesc);//打印信息
this.findByDescCallback.byDescResult(originNodeByDesc, getTransNodes(originNodeByDesc));
}
//点击事件
if (this.clickDesc != null && this.clickDesc.length == 3 && this.clickDesc[0] == 0 && this.clickDesc[1] < originNodeByDesc.size()) {
int clickNodeIndex = this.clickDesc[1];//第几个控件
int intervalMillis = this.clickDesc[2];//延时(ms)
mClickNodeByDesc = originNodeByDesc.get(clickNodeIndex);
if (descTimer == null) {
descTimer = new CountDownTimer(Integer.MAX_VALUE, intervalMillis) {
@Override
public void onTick(long l) {
performClick(mClickNodeByDesc);
}

@Override
public void onFinish() {}
};
descTimer.start();
}
}
//一次全页面搜索控件结束后清空暂存的控件列表
if (originNodeByDesc != null) {
originNodeByDesc.clear();
originNodeByDesc = null;
}
}
}

@Override
public void onInterrupt() {
releaseAllTimer();
instance = null;
TLog.d(TAG, "onInterrupt()");
}

@Override
public void onDestroy() {
super.onDestroy();
releaseAllTimer();
instance = null;
TLog.d(TAG, "onDestroy()");
}

private void releaseAllTimer() {
if (idTimer != null) {
idTimer.cancel();
idTimer = null;
}
if (textTimer != null) {
textTimer.cancel();
textTimer = null;
}
if (descTimer != null) {
descTimer.cancel();
descTimer = null;
}
}

//当前服务是否正在运行
public static boolean isRunning() {
return instance != null;
}

//模拟点击-绝对坐标
@SuppressLint("NewApi")
public void performClickAbsXY(int x, int y) {
Path path = new Path();
path.moveTo(x - 1, y - 1);
path.lineTo(x + 1, y + 1);
TLog.d(TAG, "模拟点击=>performClickAbsXY()=绝对坐标, x:" + x + ", y:" + y);
dispatchGesture(new GestureDescription.Builder().addStroke(new GestureDescription.StrokeDescription(path, 0, 100)).build(), null, null);
}

//模拟点击-控件
private void performClick(AccessibilityNodeInfo... nodes) {
if (nodes == null || nodes.length < 1) return;
for (AccessibilityNodeInfo node : nodes) {
if (!node.isClickable()) continue;
TLog.d(TAG, "模拟点击=>performClick()=控件, id:" + node.getViewIdResourceName() + ", text:" + node.getText());
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}

//模拟点击-返回
@SuppressWarnings("all")
public boolean performClickBackKey() {
TLog.d(TAG, "模拟点击=>performClickBackKey()=点击");
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
}
}

  • 简化的节点信息包装实例NodeInfo

public class NodeInfo {
private String viewIdResourceName;//app.catface.accessibility:id/bt1
private CharSequence text;
private CharSequence contentDescription;
private CharSequence className;//android.widget.Button
private CharSequence packageName;//包名
private int childCount;//子控件个数
private int[] boundsInScreen;//屏幕位置
private int[] boundsInParent;//父布局位置
private boolean isClickable;
}

  • 日志打印Tlog

public class TLog {

public static final String DEFAULT_TAG = "accessibility-test";

public static void d(String className, String msg) {
d(DEFAULT_TAG, className, msg);
}

public static void d(String tag, String className, String msg) {
Log.d(tag, "[" + className + "]" + msg);
}
}

调用示例app模块

  • activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<Button
android:id="@+id/btStartService"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_weight="1"
android:text="开启服务" />

<Button
android:id="@+id/btStopService"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_weight="1"
android:text="关闭服务" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<EditText
android:id="@+id/etDestId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:hint="控件id"
android:text="app.catface.accessibility:id/bt1" />

<Button
android:id="@+id/btSearchId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="搜索" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<EditText
android:id="@+id/etText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:hint="节点内容"
android:text="试试" />

<EditText
android:id="@+id/etTextMatchType"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="0123"
android:text="1" />

<Button
android:id="@+id/btSearchText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="搜索" />

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<EditText
android:id="@+id/etDesc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:hint="描述内容"
android:text="试试" />

<EditText
android:id="@+id/etDescMatchType"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="0123"
android:text="1" />

<Button
android:id="@+id/btSearchDesc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="搜索" />

</LinearLayout>

<Button
android:id="@+id/btClearClick"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消点击事件" />

<Button
android:id="@+id/bt2Page2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="跳转到第二页" />

<Button
android:id="@+id/btStartClick"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开启自由点击" />


<Button
android:id="@+id/btClickBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="模拟返回" />

</androidx.appcompat.widget.LinearLayoutCompat>

  • MainActivity.java

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import java.util.List;

import cc.catface.accessibility.AccessibilitySettingOpenHelper;
import cc.catface.accessibility.NodeInfo;
import cc.catface.accessibility.ProAccessibilityService;
import cc.catface.accessibility.TLog;

public class MainActivity extends AppCompatActivity implements ProAccessibilityService.FindByIdCallback, ProAccessibilityService.FindByTextCallback, ProAccessibilityService.FindByDescCallback {

@RequiresApi(api = Build.VERSION_CODES.N)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//开启无障碍服务
findViewById(R.id.btStartService).setOnClickListener(v -> {
if (!AccessibilitySettingOpenHelper.isAccessibilitySettingsOn(this, ProAccessibilityService.class.getName())) {
AccessibilitySettingOpenHelper.jumpToSettingPage(this);
} else {
Toast.makeText(this, "无障碍服务已开启", Toast.LENGTH_SHORT).show();
}
});
//关闭无障碍服务
findViewById(R.id.btStopService).setOnClickListener(v -> {
ProAccessibilityService.getInstance().disableSelf();
});
//跳转到第二页
findViewById(R.id.bt2Page2).setOnClickListener(v -> {
startActivity(new Intent(this, SecondActivity.class));
});

//设置搜索指定控件id
findViewById(R.id.btSearchId).setOnClickListener(v -> {
String id = ((EditText) findViewById(R.id.etDestId)).getText().toString();
ProAccessibilityService.getInstance().setId(id);//指定控件id如:app.catface.accessibility:id/bt1
ProAccessibilityService.getInstance().setFindByIdEnabled(this);//回调结果
ProAccessibilityService.getInstance().setClickId(new int[]{0, 0, 3000});//点击:p1=0开启点击;p2=0点击第几个控件;p3点击延时
});
//设置搜索内容text
findViewById(R.id.btSearchText).setOnClickListener(v -> {
String text = ((EditText) findViewById(R.id.etText)).getText().toString();
String typeStr = ((EditText) findViewById(R.id.etTextMatchType)).getText().toString();
//text:文本内容;p2匹配类型[0完全匹配1部分匹配2开头匹配3结尾匹配]
ProAccessibilityService.getInstance().setTextAndFilterType(text, Integer.parseInt(typeStr));
ProAccessibilityService.getInstance().setFindByTextEnabled(this);//回调结果
ProAccessibilityService.getInstance().setClickText(new int[]{0, 0, 3000});//点击:p1=0开启点击;p2=0点击第几个控件;p3点击延时
});
//设置搜索描述desc
findViewById(R.id.btSearchDesc).setOnClickListener(v -> {
String desc = ((EditText) findViewById(R.id.etDesc)).getText().toString();
String typeStr = ((EditText) findViewById(R.id.etDescMatchType)).getText().toString();
//desc:描述内容;p2匹配类型[0完全匹配1部分匹配2开头匹配3结尾匹配]
ProAccessibilityService.getInstance().setDescAndFilterType(desc, Integer.parseInt(typeStr));
ProAccessibilityService.getInstance().setFindByDescEnabled(this);//回调结果
ProAccessibilityService.getInstance().setClickDesc(new int[]{0, 0, 3000});//点击:p1=0开启点击;p2=0点击第几个控件;p3点击延时
});

//清空模拟点击
findViewById(R.id.btClearClick).setOnClickListener(v -> {
ProAccessibilityService.getInstance().setClickId(null);//清空模拟点击
ProAccessibilityService.getInstance().setClickText(null);//清空模拟点击
ProAccessibilityService.getInstance().setClickDesc(null);//清空模拟点击
});
//模拟点击绝对位置
findViewById(R.id.btStartClick).setOnClickListener(v -> {
new CountDownTimer(2000, 2000) {
@Override
public void onTick(long millisUntilFinished) {}

@Override
public void onFinish() {
ProAccessibilityService.getInstance().performClickAbsXY(5, 85);
}
}.start();
});
//模拟返回
findViewById(R.id.btClickBack).setOnClickListener(v -> {
new CountDownTimer(2000, 2000) {
@Override
public void onTick(long millisUntilFinished) {}

@Override
public void onFinish() {
ProAccessibilityService.getInstance().performClickBackKey();
}
}.start();
});
}


@Override
public void byIdResult(List<AccessibilityNodeInfo> originNodes, List<NodeInfo> nodeInfos) {
for (NodeInfo info : nodeInfos) {
TLog.d(getClass().getSimpleName(), "IDID节点#RESULT:" + info.toString());
}
}

@Override
public void byTextResult(List<AccessibilityNodeInfo> originNodes, List<NodeInfo> nodeInfos) {
for (NodeInfo info : nodeInfos) {
TLog.d(getClass().getSimpleName(), "TEXT内容#RESULT:" + info.toString());
}
}

@Override
public void byDescResult(List<AccessibilityNodeInfo> originNodes, List<NodeInfo> nodeInfos) {
for (NodeInfo info : nodeInfos) {
TLog.d(getClass().getSimpleName(), "DESC描述#RESULT:" + info.toString());
}
}
}


举报

相关推荐

0 条评论