下面列出了android.view.accessibility.AccessibilityNodeInfo#findAccessibilityNodeInfosByViewId ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* @param nodeInfo
* @param accessibilityEvent
* @return 消息列表的最后一个Item是否为视频通话结束或取消
*/
private boolean isVideoChatEnded(AccessibilityNodeInfo nodeInfo, AccessibilityEvent accessibilityEvent) {
String pkg = accessibilityEvent.getPackageName().toString();
List<AccessibilityNodeInfo> listNode = nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mobileqq:id/listView1");
AccessibilityNodeInfo tempNode = null;
try {
if (Constant.QQ_PKG.equals(pkg)) {
if (!AppUtils.isListEmpty(listNode)) {
tempNode = listNode.get(0);
tempNode = tempNode.getChild(tempNode.getChildCount() - 1);
if (tempNode != null && tempNode.getClassName().equals(RelativeLayout.class.getName())) {
return !AppUtils.isListEmpty(tempNode.findAccessibilityNodeInfosByText("拒绝"))
|| !AppUtils.isListEmpty(tempNode.findAccessibilityNodeInfosByText("通话时长"))
|| !AppUtils.isListEmpty(tempNode.findAccessibilityNodeInfosByText("取消"));
}
}
}
} finally {
if (tempNode != null) {
tempNode.recycle();
}
}
return false;
}
/**
* 查找对应ID的View
*
* @param id id
* @return View
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public AccessibilityNodeInfo findViewByID(String id) {
AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
if (accessibilityNodeInfo == null) {
return null;
}
List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId(id);
if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
if (nodeInfo != null) {
return nodeInfo;
}
}
}
return null;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public void clickTextViewByID(String id) {
AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
if (accessibilityNodeInfo == null) {
return;
}
List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId(id);
if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
if (nodeInfo != null) {
performViewClick(nodeInfo);
break;
}
}
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public static AccessibilityNodeInfo getWechatRedEnvelopeOpenDetailNode(AccessibilityNodeInfo info) {
if (info == null)
return null;
List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/b2c");
LogUtil.d("handleLuckyMoneyReceivePage");
AccessibilityNodeInfo tempNode=null;
for(int i=0;i<list.size();i++){
tempNode=list.get(i);
XLog.e("WechatAccService", "eee"+tempNode.isVisibleToUser()+"-"+tempNode.isEnabled());
if ("android.widget.TextView".equals(tempNode.getClassName())&&tempNode.isVisibleToUser()){
return tempNode;
}
}
return null;
}
void getQuestionAndOptionFromScreen(AccessibilityNodeInfo source) {
String str = "com.showtimeapp";
try {
List<AccessibilityNodeInfo> questionIDs = source.findAccessibilityNodeInfosByViewId(str + ":id/question");
List<AccessibilityNodeInfo> optionsIDs = source.findAccessibilityNodeInfosByViewId(str + ":id/answer");
int sizeOfQuestion = questionIDs.size();
if (sizeOfQuestion > 0) {
question = questionIDs.get(0).getText().toString();
option1 = optionsIDs.get(0).getText().toString();
option2 = optionsIDs.get(1).getText().toString();
option3 = optionsIDs.get(2).getText().toString();
findAnswer(question, option1, option2, option3);
questionIDs.clear();
optionsIDs.clear();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@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 swagiq(AccessibilityNodeInfo source) {
String str = "com.prodege.swagiq";
try {
List<AccessibilityNodeInfo> questionId = source.findAccessibilityNodeInfosByViewId(str + ":id/txt_question");
List<AccessibilityNodeInfo> option1id = source.findAccessibilityNodeInfosByViewId(str + ":id/lyt_answers");
int sizeOfQuestion = questionId.size();
if (sizeOfQuestion > 0) {
question = questionId.get(0).getText().toString();
option1 = option1id.get(0).getText().toString();
option2 = option1id.get(1).getText().toString();
option3 = option1id.get(2).getText().toString();
findAnswer(question, option1, option2, option3);
// isQuestionDisplayed = true;
questionId.clear();
option1id.clear();
}
} catch (Exception io) {
io.printStackTrace();
// Toast.makeText(this, "Error:::" + io.getMessage(), Toast.LENGTH_SHORT).show();
showCustomAlert("Error:Accessibility is either switch off or disabled on this screen ");
}
}
private boolean gotoView(String lookingTitle) {
// TODO 如果 app 沒有在前台需要兩次發送才成功
if (lookingTitle.equals("")) {
tellUser("配置檔不完整");
Log.i(TAG, "gotoView: Title 為空");
return false;
}
AccessibilityNodeInfo source = getRootInActiveWindow();
if (source == null) {
Log.i(TAG, "gotoView: source == null");
return false;
}
if (!source.getPackageName().equals("com.xiaomi.smarthome")) {
startApp("com.xiaomi.smarthome");
}
List<AccessibilityNodeInfo> viewTitle = source.findAccessibilityNodeInfosByViewId("com.xiaomi.smarthome:id/module_a_2_more_title");
if (!titleCheck(lookingTitle, viewTitle)) {
List<AccessibilityNodeInfo> menuBtn = source.findAccessibilityNodeInfosByViewId("com.xiaomi.smarthome:id/drawer_btn");
doClick(menuBtn);
List<AccessibilityNodeInfo> backBtn = source.findAccessibilityNodeInfosByViewId("com.xiaomi.plugseat:id/title_bar_return");
doClick(backBtn);
List<AccessibilityNodeInfo> apiBtn = getRootInActiveWindow().findAccessibilityNodeInfosByText(lookingTitle);
Log.i(TAG, "gotoView: " + apiBtn);
if (apiBtn != null)
for (AccessibilityNodeInfo n : apiBtn) {
n.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
return false;
} else {
return true;
}
}
private void justplay(AccessibilityNodeInfo source) {
String str = "com.beamnext.jusplay";
try {
List<AccessibilityNodeInfo> questionId = source.findAccessibilityNodeInfosByViewId(str + ":id/titleTextView");
List<AccessibilityNodeInfo> option1ID = source.findAccessibilityNodeInfosByViewId(str + ":id/answer1TV");
List<AccessibilityNodeInfo> option2ID = source.findAccessibilityNodeInfosByViewId(str + ":id/answer2TV");
List<AccessibilityNodeInfo> option3ID = source.findAccessibilityNodeInfosByViewId(str + ":id/answer3TV");
int sizeOfQuestion = questionId.size();
if (sizeOfQuestion > 0) {
question = questionId.get(0).getText().toString();
option1 = option1ID.get(0).getText().toString();
option2 = option2ID.get(0).getText().toString();
option3 = option3ID.get(0).getText().toString();
findAnswer(question, option1, option2, option3);
questionId.clear();
option1ID.clear();
option2ID.clear();
option3ID.clear();
}
} catch (Exception io) {
io.printStackTrace();
// Toast.makeText(this, "Error:::" + io.getMessage(), Toast.LENGTH_SHORT).show();
showCustomAlert("Error:Accessibility is either switch off or disabled on this screen ");
}
}
private void mobshow(AccessibilityNodeInfo source) {
String str = "com.portkey.mobshow";
try {
List<AccessibilityNodeInfo> questionId = source.findAccessibilityNodeInfosByViewId(str + ":id/question_text");
List<AccessibilityNodeInfo> option1ID = source.findAccessibilityNodeInfosByViewId(str + ":id/option_button_a");
List<AccessibilityNodeInfo> option2ID = source.findAccessibilityNodeInfosByViewId(str + ":id/option_button_b");
List<AccessibilityNodeInfo> option3ID = source.findAccessibilityNodeInfosByViewId(str + ":id/option_button_c");
int sizeOfQuestion = questionId.size();
if (sizeOfQuestion > 0) {
question = questionId.get(0).getText().toString();
option1 = option1ID.get(0).getText().toString();
option2 = option2ID.get(0).getText().toString();
option3 = option3ID.get(0).getText().toString();
findAnswer(question, option1, option2, option3);
questionId.clear();
option1ID.clear();
option2ID.clear();
option3ID.clear();
}
} catch (Exception io) {
io.printStackTrace();
// Toast.makeText(this, "Error:::" + io.getMessage(), Toast.LENGTH_SHORT).show();
showCustomAlert("Error:Accessibility is either switch off or disabled on this screen ");
}
}
private void hq(AccessibilityNodeInfo source) {
String str = "com.intermedia.hq";
try {
List<AccessibilityNodeInfo> questionId = source.findAccessibilityNodeInfosByViewId(str + ":id/question");
List<AccessibilityNodeInfo> option1ID = source.findAccessibilityNodeInfosByViewId(str + ":id/answer_button_one");
List<AccessibilityNodeInfo> option2ID = source.findAccessibilityNodeInfosByViewId(str + ":id/answer_button_two");
List<AccessibilityNodeInfo> option3ID = source.findAccessibilityNodeInfosByViewId(str + ":id/answer_button_three");
int sizeOfQuestion = questionId.size();
if (sizeOfQuestion > 0) {
question = questionId.get(0).getText().toString();
option1 = option1ID.get(0).getText().toString();
option2 = option2ID.get(0).getText().toString();
option3 = option3ID.get(0).getText().toString();
findAnswer(question, option1, option2, option3);
questionId.clear();
option1ID.clear();
option2ID.clear();
option3ID.clear();
}
} catch (Exception io) {
io.printStackTrace();
// Toast.makeText(this, "Error:::" + io.getMessage(), Toast.LENGTH_SHORT).show();
showCustomAlert("Error:Accessibility is either switch off or disabled on this screen ");
}
}
private void qureka(AccessibilityNodeInfo source) {
String str = "qureka.live.game.show";
try {
List<AccessibilityNodeInfo> questionId = source.findAccessibilityNodeInfosByViewId(str + ":id/question");
List<AccessibilityNodeInfo> option1ID = source.findAccessibilityNodeInfosByViewId(str + ":id/option_one");
List<AccessibilityNodeInfo> option2ID = source.findAccessibilityNodeInfosByViewId(str + ":id/option_two");
List<AccessibilityNodeInfo> option3ID = source.findAccessibilityNodeInfosByViewId(str + ":id/option_three");
int sizeOfQuestion = questionId.size();
if (sizeOfQuestion > 0) {
question = questionId.get(0).getText().toString();
option1 = option1ID.get(0).getText().toString();
option2 = option2ID.get(0).getText().toString();
option3 = option3ID.get(0).getText().toString();
findAnswer(question, option1, option2, option3);
questionId.clear();
option1ID.clear();
option2ID.clear();
option3ID.clear();
}
} catch (Exception io) {
// Toast.makeText(this, "Error:::" + io.getMessage(), Toast.LENGTH_SHORT).show();
showCustomAlert("Error:Accessibility is either switch off or disabled on this screen ");
}
}
private void brainbazzi(AccessibilityNodeInfo source) {
String str = "com.brainbaazi";
try {
List<AccessibilityNodeInfo> questionId = source.findAccessibilityNodeInfosByViewId(str + ":id/text_question");
List<AccessibilityNodeInfo> option1ID = source.findAccessibilityNodeInfosByViewId(str + ":id/button_option1");
List<AccessibilityNodeInfo> option2ID = source.findAccessibilityNodeInfosByViewId(str + ":id/button_option2");
List<AccessibilityNodeInfo> option3ID = source.findAccessibilityNodeInfosByViewId(str + ":id/button_option3");
int sizeOfQuestion = questionId.size();
if (sizeOfQuestion > 0) {
question = questionId.get(0).getText().toString();
option1 = option1ID.get(0).getText().toString();
option2 = option2ID.get(0).getText().toString();
option3 = option3ID.get(0).getText().toString();
findAnswer(question, option1, option2, option3);
questionId.clear();
option1ID.clear();
option2ID.clear();
option3ID.clear();
}
} catch (Exception io) {
showCustomAlert("Error:Accessibility is either switch off or disabled on this screen ");
}
}
/**
*
* @param root is the rootview of a given page.
* @param packageName denotes the related app for this given page.
* @return A list of accessibility node infos representing a list of messages in a given chat app
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public static List<AccessibilityNodeInfo> getMessageList(AccessibilityNodeInfo root, String packageName){
if(root!=null)
return root.findAccessibilityNodeInfosByViewId(getMessageListResourceId(packageName));
else
return new ArrayList<>();
}
/**
* Find out the unread message amount for each of the user
* @param root
* @param appName
* @return A two dimensional array of name and unread message count
*/
public static Map<String,Integer> getUnreadMessageList(AccessibilityNodeInfo root, String appName){
try{
Map<String,Integer> unreadMessageList = new HashMap<>();
List<AccessibilityNodeInfo> containers = root.findAccessibilityNodeInfosByViewId(
getMainPageContainerResourceId(appName));
for (AccessibilityNodeInfo container : containers){
String name = String.valueOf(container.findAccessibilityNodeInfosByViewId(
getMainPageContactNameResourceId(appName)).get(0).getText());
List<AccessibilityNodeInfo> a = container.findAccessibilityNodeInfosByViewId(
getMainpageMessageCountResourceId(appName));
int messageCount = 0;
if(!a.isEmpty()){
AccessibilityNodeInfo messageCountNode = container.findAccessibilityNodeInfosByViewId(
getMainpageMessageCountResourceId(appName)).get(0);
if(messageCountNode!=null) {
messageCount = Integer.parseInt(messageCountNode.getText().toString());
}
}
unreadMessageList.put(name,messageCount);
}
if(!unreadMessageList.isEmpty()){
return unreadMessageList;
}
}
catch (Exception exception){
return null;
}
return null;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private void click(String clickId) {
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
if (nodeInfo != null) {
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId(clickId);
for (AccessibilityNodeInfo item : list) {
item.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
/**
* 好友:
* 姓名 last-3 android.widget.TextView
* 消息 5-[]-last android.widget.TextView focusable
* 文本框 7-0 android.widget.EditText
* 发送按钮 7-1 android.widget.Button
* <p>
* 群:
* 群名 1
* 消息 4/5-
* <p>
* 群里的临时会话:
* 姓名 1-0
* 消息 6-[]-last
* 文本框 8-0
* 发送按钮 8-1
*/
protected boolean init(AccessibilityNodeInfo root) {
if (root.getChildCount() < 10) {
// 正常是13
// 有其他消息是14
// 非好友是10
Log.v(TAG, "init: root.childCount: " + root.getChildCount());
return false;
}
// List<AccessibilityNodeInfo> inputList;
// List<AccessibilityNodeInfo> sendList;
// inputList = root.findAccessibilityNodeInfosByViewId(IdInput);
// sendList = root.findAccessibilityNodeInfosByViewId(IdSend);
// if (inputList.size() == 0) {
// Log.d(TAG, "init: input is null, return");
// return false;
// }
// if (sendList.size() == 0) {
// Log.d(TAG, "init: send button is null, return");
// return false;
// }
// inputNode = inputList.get(0);
// sendBtnNode = sendList.get(0);
List<AccessibilityNodeInfo> titleList;
titleList = root.findAccessibilityNodeInfosByViewId(IdTitle);
if (titleList.size() == 0) {
Log.d(TAG, "init: title is null, return");
return false;
}
titleNode = titleList.get(0);
if (titleNode.getText() == null) {
Log.d(TAG, "init: name is null,return");
return false;
}
title = titleNode.getText() + "";
chatGroupViewNode = root.getChild(0);
if (chatGroupViewNode == null) {
Log.d(TAG, "init: chatView node is null, return");
return false;
}
if (!IdChatGroupView.equals(chatGroupViewNode.getViewIdResourceName())) {
Log.d(TAG, "init: not chat view, return");
return false;
}
isOtherMsg = IdOtherMsg.equals(root.getChild(1).getViewIdResourceName());
return true;
}
/**
* 好友:
* 姓名 1 android.widget.TextView
* 消息 5-[]-last android.widget.TextView focusable
* 文本框 7-0 android.widget.EditText
* 发送按钮 7-1 android.widget.Button
* <p>
* 群:
* 群名 1
* 消息 4/5-
* <p>
* 群里的临时会话:
* 姓名 1-0
* 消息 6-[]-last
* 文本框 8-0
* 发送按钮 8-1
*/
protected boolean init(AccessibilityNodeInfo root) {
//16 是其他界面
//14 是没有聊过天
//12 是发送完消息
if (root.getChildCount() < 12) {
Log.v(TAG, "init: root.childCount: " + root.getChildCount());
return false;
}
// List<AccessibilityNodeInfo> inputList;
// List<AccessibilityNodeInfo> sendList;
// inputList = root.findAccessibilityNodeInfosByViewId(IdInput);
// sendList = root.findAccessibilityNodeInfosByViewId(IdSend);
// if (inputList.size() == 0) {
// Log.d(TAG, "init: input is null, return");
// return false;
// }
// if (sendList.size() == 0) {
// Log.d(TAG, "init: send button is null, return");
// return false;
// }
// inputNode = inputList.get(0);
// sendBtnNode = sendList.get(0);
List<AccessibilityNodeInfo> titleList;
titleList = root.findAccessibilityNodeInfosByViewId(IdTitle);
if (titleList.size() == 0) {
Log.d(TAG, "init: title is null, return");
return false;
}
titleNode = titleList.get(0);
if (titleNode.getText() == null) {
Log.d(TAG, "init: name is null,return");
return false;
}
title = titleNode.getText() + "";
isOtherMsg = false;
for (int i = 4; i < 7; i++) {
AccessibilityNodeInfo child = root.getChild(i);
String name = child.getViewIdResourceName();
if (name == null)
continue;
switch (name) {
case IdChatGroupView:
chatGroupViewNode = child;
break;
case IdOtherMsg:
otherMsgNode = child;
isOtherMsg = true;
break;
}
}
if (chatGroupViewNode == null) {
Log.i(TAG, "init: chatGroupViewNode is null, return");
return false;
}
return true;
}
private void getWeChatLog(AccessibilityNodeInfo rootNode) {
if (rootNode != null) {
//获取所有聊天的线性布局
List<AccessibilityNodeInfo> listChatRecord =
rootNode.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/o");
if (listChatRecord.size() == 0) {
return;
}
//获取最后一行聊天的线性布局(即是最新的那条消息)
AccessibilityNodeInfo finalNode = listChatRecord.get(listChatRecord.size() - 1);
//获取聊天对象list(其实只有size为1)
List<AccessibilityNodeInfo> imageName =
finalNode.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/i_");
//获取聊天信息list(其实只有size为1)
List<AccessibilityNodeInfo> record =
finalNode.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/ib");
if (imageName.size() != 0) {
if (record.size() == 0) {
//判断当前这条消息是不是和上一条一样,防止重复
if (!chatRecord.equals("对方发的是图片或者表情")) {
//获取聊天对象
chatName = imageName.get(0).getContentDescription().toString().replace("头像", "");
//获取聊天信息
chatRecord = "对方发的是图片或者表情";
Log.e("AAAA", chatName + ":" + "对方发的是图片或者表情");
}
} else {
//判断当前这条消息是不是和上一条一样,防止重复
if (!chatRecord.equals(record.get(0).getText().toString())) {
//获取聊天对象
chatName = imageName.get(0).getContentDescription().toString().replace("头像", "");
//获取聊天信息
chatRecord = record.get(0).getText().toString();
Log.e("AAAA", chatName + ":" + chatRecord);
}
}
}
}
}
public void testAirplaneModeToOn() {
UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
// Activityの起動を監視するリスナーをセット
mMainLaunched = false;
uiAutomation
.setOnAccessibilityEventListener(new OnAccessibilityEventListener() {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
// ウィンドウのコンテンツが変わった
if (TARGET_PKG.equals(event.getPackageName())) {
// MainActivityが起動した
mMainLaunched = true;
}
}
}
});
// MainActivity起動
Activity target = launchActivity(TARGET_PKG, MainActivity.class, null);
try {
// MainActivity起動待ち
do {
Thread.sleep(1000);
} while (!mMainLaunched);
// 機内モードをOnにする
// Settingsの起動
Intent intent = new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getInstrumentation().getContext().startActivity(intent);
// Settingsの起動待ち
AccessibilityNodeInfo root;
while (true) {
root = uiAutomation.getRootInActiveWindow();
if (root != null && SETTINGS_PKG.equals(root.getPackageName())) {
break;
} else {
Thread.sleep(1000);
}
}
// ボタンを押す
List<AccessibilityNodeInfo> list = root
.findAccessibilityNodeInfosByViewId("android:id/list");
AccessibilityNodeInfo listViewInfo = list.get(0);
AccessibilityNodeInfo airplaneModeView = listViewInfo.getChild(0);
List<AccessibilityNodeInfo> checkList = airplaneModeView
.findAccessibilityNodeInfosByViewId("android:id/checkbox");
AccessibilityNodeInfo airplaneModeCheck = checkList.get(0);
if (!airplaneModeCheck.isChecked()) {
airplaneModeView.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
// Backキーを押してSettingsの終了
uiAutomation.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
// 機内モード反映待ち
Thread.sleep(10000);
// TextViewの文字列検証
String expected = target
.getString(org.techbooster.uiautomationsample.R.string.airplane_mode_off);
TextView textView = (TextView) target
.findViewById(org.techbooster.uiautomationsample.R.id.text_view);
assertEquals(expected, textView.getText().toString());
} catch (Exception e) {
fail(e.getMessage());
e.printStackTrace();
} finally {
if (target != null) {
target.finish();
}
}
}