起因:
最近做的APP中有一个新功能:已知用户微信号,可点击直接跳转到当前用户微信聊天窗口页面。
当时第一想法是使用无障碍来做,并且觉得应该不难,只是逻辑有点复杂。没想到最终踩了好多坑,特地把踩过的坑记录下来。
实现逻辑:
在APP中点击按钮→跳转到微信界面→模拟点击微信搜索按钮→在微信搜索页面输入获取的微信号→模拟点击查询到的用户进入用户聊天界面。
效果图:
实现过程:
跳转微信按钮点击事件:
1 jumpButton.setOnClickListener(new View.OnClickListener() { 2 @Override 3 public void onClick(View view) { 4 Intent intent = new Intent(Intent.ACTION_MAIN); 5 ComponentName cmp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI"); 6 intent.addCategory(Intent.CATEGORY_LAUNCHER); 7 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8 intent.setComponent(cmp); 9 startActivity(intent); 10 } 11 });
无障碍监听主要方法:
一些必要的参数:
1 /** 2 * 微信主页面的“搜索”按钮id 3 */ 4 private final String SEARCH_ID = "com.tencent.mm:id/ij"; 5 6 /** 7 * 微信主页面bottom的“微信”按钮id 8 */ 9 private final String WECHAT_ID = "com.tencent.mm:id/d3t"; 10 11 /** 12 * 微信搜索页面的输入框id 13 */ 14 private final String EDIT_TEXT_ID = "com.tencent.mm:id/ka"; 15 16 /** 17 * 微信搜索页面活动id 18 */ 19 private String SEARCH_ACTIVITY_NAME = "com.tencent.mm.plugin.fts.ui.FTSMainUI"; 20 21 private String LIST_VIEW_NAME = "android.widget.ListView";
微信组件的id之前有博客说过如何获取,所以在此就不重复说明了。
监听主要方法:
1 @Override 2 public void onAccessibilityEvent(AccessibilityEvent event) { 3 List<AccessibilityNodeInfo> searchNode = event.getSource().findAccessibilityNodeInfosByViewId(SEARCH_ID); 4 List<AccessibilityNodeInfo> wechatNode = event.getSource().findAccessibilityNodeInfosByViewId(WECHAT_ID); 5 6 if (searchNode.size() > 1) { 7 // 点击“搜索”按钮 8 if (searchNode.get(0).getParent().isClickable()) { 9 searchNode.get(0).getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK); 10 return; 11 } 12 } else if (searchNode.size() == 1) { 13 // 如果在“我”页面,则进入“微信”页面 14 for (AccessibilityNodeInfo info : wechatNode) { 15 if (info.getText().toString().equals("微信") && !info.isChecked()) { 16 17 if (info.getParent().isClickable()) { 18 info.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK); 19 return; 20 } 21 break; 22 } 23 } 24 } 25 26 // 当前页面是搜索页面 27 if (SEARCH_ACTIVITY_NAME.equals(event.getClassName().toString())) { 28 List<AccessibilityNodeInfo> editTextNode = event.getSource().findAccessibilityNodeInfosByViewId(EDIT_TEXT_ID); 29 30 if (editTextNode.size() > 0) { 31 // 输入框内输入查询的微信号 32 Bundle arguments = new Bundle(); 33 arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, Constant.wechatId); 34 editTextNode.get(0).performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments); 35 } 36 } else if (LIST_VIEW_NAME.equals(event.getClassName().toString())) { 37 // 如果监听到了ListView的内容改变,则找到查询到的人,并点击进入 38 List<AccessibilityNodeInfo> textNodeList = event.getSource().findAccessibilityNodeInfosByText("微信号: " + Constant.wechatId); 39 if (textNodeList.size() > 0) { 40 textNodeList.get(0).getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK); 41 } 42 } 43 44 }
这是最原始的版本,具体逻辑已在注释中说明。
遇到的坑:
1. 搜索内容无法赋值给搜索框
最开始以为是赋值的方法有问题,但是在调试状态下能够赋值成功。因此猜测是因为UI加载太慢的缘故。
在搜索框还没完全加载完全的时候就进行了赋值,因此赋值不成