下面列出了android.view.accessibility.AccessibilityNodeInfo#findAccessibilityNodeInfosByText ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 查找符合条件的节点
* @param service {@link AccessibilityService}
* @param text 文本内容 ( 搜索包含该文本内容的节点 )
* @param className 节点所属的类 ( 类名 )
* @return 包含该文本内容, 且属于指定类的节点集合
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public static List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(final AccessibilityService service, final String text, final String className) {
if (service == null || text == null || className == null) return null;
List<AccessibilityNodeInfo> lists = new ArrayList<>();
// 获取根节点
AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow();
// 取得当前激活窗体的根节点
if (nodeInfo == null) return lists;
// 通过文字找到当前的节点
List<AccessibilityNodeInfo> nodes = nodeInfo.findAccessibilityNodeInfosByText(text);
for (int i = 0; i < nodes.size(); i++) {
AccessibilityNodeInfo node = nodes.get(i);
// 判断是否符合的类型
if (node.getClassName().equals(className) && node.isEnabled()) {
// 保存符合条件
lists.add(node);
}
}
return lists;
}
/**
* 查找对应文本的View
*
* @param text text
* @param clickable 该View是否可以点击
* @return View
*/
public AccessibilityNodeInfo findViewByText(String text, boolean clickable) {
AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
if (accessibilityNodeInfo == null) {
return null;
}
List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByText(text);
if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
if (nodeInfo != null && (nodeInfo.isClickable() == clickable)) {
return nodeInfo;
}
}
}
return null;
}
/**
* 查找对应文本的View
*
* @param text text
* @param clickable 该View是否可以点击
* @return View
*/
public List<AccessibilityNodeInfo> findViewListByText(String text, boolean clickable) {
List<AccessibilityNodeInfo> accessibilityNodeInfoList = new ArrayList<>();
AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
if (accessibilityNodeInfo == null) {
return null;
}
List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByText(text);
if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
if (nodeInfo != null && (nodeInfo.isClickable() == clickable)) {
accessibilityNodeInfoList.add(nodeInfo);
}
}
}
return accessibilityNodeInfoList;
}
/**
* @param nodeInfo
* @param accessibilityEvent
* @return If from notification ,msg format :{@link Constant#MONITOR_TAG} + ":real QQ No: "+{@link Constant#MONITOR_CMD_VIDEO}
*/
private String retrieveQQNumber(AccessibilityNodeInfo nodeInfo, AccessibilityEvent accessibilityEvent) {
if (accessibilityEvent.getEventType() == TYPE_NOTIFICATION_STATE_CHANGED) {
Parcelable data = accessibilityEvent.getParcelableData();
if (data instanceof Notification) {
if (((Notification) data).tickerText != null) {
return ((Notification) data).tickerText.toString().split(":")[1];
}
}
} else {
List<AccessibilityNodeInfo> nodeInfos = nodeInfo.findAccessibilityNodeInfosByText(MONITOR_TAG);
if (!AppUtils.isListEmpty(nodeInfos)) {
String tag;
for (AccessibilityNodeInfo info : nodeInfos) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "retrieveQQNumber: " + info.getText());
}
tag = (String) info.getText();
if (!TextUtils.isEmpty(tag) && tag.contains(MONITOR_TAG)) {
return tag.substring(Constant.MONITOR_TAG.length());
}
}
}
}
return Privacy.QQ_NUMBER;
}
@SuppressLint({"NewApi"})
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
switch (accessibilityEvent.getEventType()) {
case 32:
String charSequence = accessibilityEvent.getClassName().toString();
System.out.println(charSequence);
if (charSequence.equals(ッ)) {
AccessibilityNodeInfo rootInActiveWindow = getRootInActiveWindow();
if (rootInActiveWindow != null) {
for (AccessibilityNodeInfo accessibilityNodeInfo : rootInActiveWindow.findAccessibilityNodeInfosByText(キ)) {
accessibilityNodeInfo.performAction(1);
}
}
return;
}
return;
default:
}
}
/**
* 查找对应文本的View
*
* @param text text
* @param clickable clickable
*/
public AccessibilityNodeInfo findViewByText(String text, boolean clickable) {
AccessibilityNodeInfo rootNodeInfo = getRootInActiveWindow();
if (rootNodeInfo == null) {
return null;
}
List<AccessibilityNodeInfo> nodeInfoList = rootNodeInfo.findAccessibilityNodeInfosByText(text);
if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
if (nodeInfo != null && (nodeInfo.isClickable() == clickable)) {
return nodeInfo;
}
}
}
return null;
}
/**
* 搜索包含红包的UI节点, 点击所有
*
* @param root 根UI节点
* @return 成功点击的红包数
*/
Integer getFromNode(AccessibilityNodeInfo root)
{
List<AccessibilityNodeInfo> mNodes =
root.findAccessibilityNodeInfosByText(getResources().getString(R.string.chat_pattern));
for (AccessibilityNodeInfo node : mNodes)
{
// Log.d("node", node.toString());
AccessibilityNodeInfo parent = node.getParent();
if (parent == null)
{
//Log.d("node.parent", "null"); // 有时候没有父节点, 蜜汁bug
}
else
{
//Log.d("click", "GET" + Integer.valueOf(node.hashCode()).toString());
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); // TextView不能点, 点的是ListView, 详情查看clickable
cnt_get += 1;
lastNode = node.hashCode();
}
}
return mNodes.size(); // 即搜索结果数目
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void checkKey1()
{
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
if (nodeInfo == null)
return;
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("拆红包");
if (list == null || list.size() == 0)
{
list = nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/b2c");
}
for (AccessibilityNodeInfo n : list)
{
n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
private void openNext2(String str, AccessibilityNodeInfo nodeInfo, final AccessibilityService service) {
if (nodeInfo == null) {
L.d("rootWindow为空");
return;
} else {
L.d("openNext2 " + nodeInfo.getText());
}
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText(str);
if (list.isEmpty()) {
return;
} else {
CharSequence text = list.get(list.size() - 1).getText();
if (TextUtils.isEmpty(text)) {
return;
} else {
L.d("openNext2 " + text);
}
}
i++;
if (isGo) {
isGo = false;
}
}
private static void startHello(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null) {
L.d("rootWindow为空");
return;
}
final List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("打招呼");
if (list == null || list.isEmpty()) {
return;
}
if (list.size() > 0) {
final AccessibilityNodeInfo info = list.get(list.size() - 1);
final AccessibilityNodeInfo parent = info.getParent();
if (parent == null) {
L.e("parent is null");
return;
}
info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
/**
* 查找符合条件的节点
* @param service {@link AccessibilityService}
* @param text 文本内容 ( 搜索包含该文本内容的节点 )
* @return 包含该文本内容的节点集合
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public static List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(final AccessibilityService service, final String text) {
if (service == null || text == null) return null;
// 获取根节点
AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow();
// 取得当前激活窗体的根节点
if (nodeInfo == null) return null;
// 通过文字找到当前的节点
return nodeInfo.findAccessibilityNodeInfosByText(text);
}
/**
* performClickActionWithFindNode.
* @param aAccessibilityNodeInfo aAccessibilityNodeInfo
* @param aClassName aClassName
* @param aNodeTxt aNodeTxt
* @param isGlobal isGlobal
* @return true
*/
private boolean performClickActionWithFindNode(AccessibilityNodeInfo aAccessibilityNodeInfo, String aClassName, String aNodeTxt, boolean isGlobal) {
if(aAccessibilityNodeInfo == null) {
return false;
} else {
List<AccessibilityNodeInfo> targetList = aAccessibilityNodeInfo.findAccessibilityNodeInfosByText(aNodeTxt);
if (targetList != null) {
for (AccessibilityNodeInfo targetNode : targetList) {
if (aClassName != null) {
String targetClassName = targetNode.getClassName() == null ? "" : targetNode.getClassName().toString();
if (!aClassName.equals(targetClassName)) {
continue;
}
}
String targetNodeText = targetNode.getText() == null ? "" : targetNode.getText().toString();
if (!aNodeTxt.equals(targetNodeText)) {
continue;
}
if (isGlobal && !isAutoRunning) {
performGlobalAction(AccessibilityNodeInfo.ACTION_FOCUS);
} else {
performClickAction(targetNode);
}
return true;
}
}
}
return false;
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public static AccessibilityNodeInfo getLastWechatRedEnvelopeNodeByText(AccessibilityNodeInfo info,Context context) {
if (info == null)
return null;
List<AccessibilityNodeInfo> resultList = info.findAccessibilityNodeInfosByText(context.getString(R.string.wechat_acc_service_red_envelope_list_identification));
if(resultList!=null && !resultList.isEmpty()) {
for(int i = resultList.size() - 1; i >= 0; i --) {
AccessibilityNodeInfo parent = resultList.get(i).getParent();
if(parent != null) {
return parent;
}
}
}
return null;
}
/**
* 批量化执行AccessibilityNodeInfo.findAccessibilityNodeInfosByText(text).
* 由于这个操作影响性能,将所有需要匹配的文字一起处理,尽早返回
*
* @param nodeInfo 窗口根节点
* @param texts 需要匹配的字符串们
* @return 匹配到的节点数组
*/
private List<AccessibilityNodeInfo> findAccessibilityNodeInfosByTexts(AccessibilityNodeInfo nodeInfo, String[] texts) {
for (String text : texts) {
if (text == null) continue;
List<AccessibilityNodeInfo> nodes = nodeInfo.findAccessibilityNodeInfosByText(text);
if (!nodes.isEmpty()) return nodes;
}
return new ArrayList<>();
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
if (eventType == TYPE_NOTIFICATION_STATE_CHANGED) {
unlockScreen();
luckyClicked = false;
}
if (eventType == TYPE_WINDOW_CONTENT_CHANGED) {
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
if (null == rootNode) return;
List<AccessibilityNodeInfo> list = rootNode.findAccessibilityNodeInfosByText(getString(R.string.get_lucky));
if (null == list || list.size() == 0) return;
AccessibilityNodeInfo parent = list.get(list.size() - 1);
while (null != parent) {
if (parent.isClickable() && !luckyClicked) {
parent.performAction(ACTION_CLICK);
luckyClicked = true;
break;
}
parent = parent.getParent();
}
}
if (eventType == TYPE_WINDOW_STATE_CHANGED) {
String clazzName = event.getClassName().toString();
if (clazzName.equals(UI_RECEIVE)) {
traverseNode(event.getSource());
}
if (clazzName.equals(UI_DETAIL) && hasLucky) {
hasLucky = false;
handler.sendEmptyMessageDelayed(MSG_BACK, 1000);
}
}
}
/**
* 搜索包含红包的UI节点, 点击末几个
*
* @param root 根UI节点
* @param size 点击最后size个
* @param ignoreDup 是否无视重复检测
* @return 成功点击的红包数
*/
Integer getFromLastNode(AccessibilityNodeInfo root, Integer size, boolean ignoreDup)
{
List<AccessibilityNodeInfo> mNodes =
root.findAccessibilityNodeInfosByText(getResources().getString(R.string.chat_pattern));
size = Math.min(size, mNodes.size()); // 先设成功点击数为预计点击的红包数目
for (Integer i = mNodes.size() - size; i < mNodes.size(); i++)
{
AccessibilityNodeInfo node = mNodes.get(i);
// Log.d("node", node.toString());
AccessibilityNodeInfo parent = node.getParent();
if (parent == null)
{
//Log.d("node.parent", "null"); // 有时候没有父节点, 蜜汁bug
}
else
{
if (ignoreDup || (lastNode != node.hashCode()))
{ // 非重复红包, 点击
// Log.d("click", "GET" + Integer.valueOf(node.hashCode()).toString());
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
cnt_get += 1;
lastNode = node.hashCode();
}
else
{
// Log.d("node duplicate", Integer.valueOf(node.hashCode()).toString());
size -= 1; // 重复红包, 减少成功计数
}
}
}
return size;
}
/**
* extractNode.
* @param aAccessibilityEvent aAccessibilityEvent
* @param aNodeClassName aNodeClassName
* @param aNodeText aNodeText
* @return AccessibilityNodeInfo
*/
private AccessibilityNodeInfo extractNode(AccessibilityEvent aAccessibilityEvent, String aNodeClassName, String aNodeText) {
List<AccessibilityNodeInfo> extractList = null;
AccessibilityNodeInfo targetNode = null;
AccessibilityNodeInfo rootNode;
if((aAccessibilityEvent == null) || (aAccessibilityEvent.getSource() == null)) {
rootNode = this.getRootInActiveWindow();
if(rootNode != null) {
extractList = rootNode.findAccessibilityNodeInfosByText(aNodeText);
}
} else {
extractList = aAccessibilityEvent.getSource().findAccessibilityNodeInfosByText(aNodeText);
}
if ((extractList == null) || extractList.isEmpty()) {
targetNode = null;
} else {
Iterator<AccessibilityNodeInfo> it = extractList.iterator();
AccessibilityNodeInfo tempNode = null;
while (it.hasNext()) {
tempNode = it.next();
if (!tempNode.getClassName().equals(aNodeClassName)) {
continue;
}
String nodeName = (tempNode.getText() == null) ? "" : tempNode.getText().toString();
if (!nodeName.endsWith(aNodeText)) {
continue;
}
targetNode = tempNode;
break;
}
}
return targetNode;
}
private void getAllHongBao(AccessibilityNodeInfo info)
{
runState = true;
//Log.i(TAG, "获取所有红包");
time = System.currentTimeMillis();
List<AccessibilityNodeInfo> list=new ArrayList<AccessibilityNodeInfo>();
//查找出当前页面所有的红包,包括手气红包和口令红包
for (String word:QQ_KEYWORD_HONGBAO)
{
List<AccessibilityNodeInfo> infolist = info.findAccessibilityNodeInfosByText(word);
if (!infolist.isEmpty())
{
for (AccessibilityNodeInfo node:infolist)
{
//这里进行过滤可点击的红包,放到后面去过滤的话感觉非常操蛋
if (node.getText() == null ||!node.getText().toString().equals(word) ||node.getParent().getChildCount() != 3 ||!node.getParent().findAccessibilityNodeInfosByText(QQ_KEYWORD_FAILD_CLICK).isEmpty())
continue;
list.add(node);
}
}
}
if (list.size() == 0)
{
runState = false;
return ;
}
ToastUtil.show(this,list.size()+"/"+(System.currentTimeMillis() - time) + "", Toast.LENGTH_SHORT);
//Log.i(TAG, "数量>>>" + list.size() + " 获取红包耗时:" + (System.currentTimeMillis() - time) + "ms");
clickAction(list);
}
public static AccessibilityNodeInfo findNodeInfosByText(AccessibilityNodeInfo nodeInfo, String text) {
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText(text);
if(list == null || list.isEmpty()) {
return null;
}
return list.get(0);
}
/**
* 点击匹配的nodeInfo
*
* @param str text关键字
*/
public static boolean openNext(AccessibilityNodeInfo nodeInfo, String str) {
if (nodeInfo == null) {
L.d("rootWindow为空");
return false;
}
final List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText(str);
if (list == null || list.isEmpty()) {
return false;
}
if (list != null && list.size() > 0) {
final AccessibilityNodeInfo info = list.get(list.size() - 1);
if (info == null) {
return false;
}
final AccessibilityNodeInfo parent = info.getParent();
if(parent == null) {
return false;
}
// new Thread(new Runnable() {
// @Override
// public void run() {
// Looper.prepare();
// try {
// sleep(2000);
//// info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
// parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }).start();
info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
return true;
} else {
// Toast.makeText(this, "找不到有效的节点", Toast.LENGTH_SHORT).show();
}
return false;
}