我曾试图在一篇博文中总结我是如何解决这个问题的。任何需要帮助的人都可以看看它。
无障碍服务更上一层楼
我之前的回答被版主删除了,可能是因为我刚刚发布了一个博客链接。所以我也在这里再次发布我的答案和详细信息。
最简单的方法是android自己提供的。如果您在自己的应用程序上构建一些东西,这是最好和最简单的方法。您必须使用“findAccessibilityNodeInfosByViewId ()”,如下所述
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
return;
}
List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId = source.findAccessibilityNodeInfosByViewId("YOUR PACKAGE NAME:id/RESOURCE ID FROM WHERE YOU WANT DATA");
if (findAccessibilityNodeInfosByViewId.size() > 0) {
AccessibilityNodeInfo parent = (AccessibilityNodeInfo) findAccessibilityNodeInfosByViewId.get(0);
// You can also traverse the list if required data is deep in view hierarchy.
String requiredText = parent.getText().toString();
Log.i("Required Text", requiredText);
}
}
如果您正在其他应用程序上构建某些东西并且不知道 res id。您必须结合父级、子级计数、找到数据的级别、事件类型来构建逻辑。您必须在事件或源中寻找模式或上述值的组合,以获取所需的数据。此外,您必须在代码中进行一些调整,以根据您的任务获取准确的数据。就像在我们的任务中一样,我们有一些正则表达式来获取宝贵的数据。
您必须注意,如果视图或 UI 发生更改或 res id 发生更改,您当前的逻辑可能会失败。因此,您必须密切关注您正在构建服务的应用程序。以下是一些示例代码,我们在其中获取没有 res id 的数据,这可能有助于您了解它的工作原理。
打印源和事件
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
return;
}
Log.i("Event", event.toString() + "");
Log.i("Source", source.toString() + "");
}
获取 childcount
source.getChildCount();
如果孩子数> 0,您可能需要调查它。
示例代码 1
if (level == 0 && source.getClassName().equals("android.widget.TextView") && source.getText()!=null && !source.getText().toString().isEmpty()){
// here level is iteration of for loop
String recivedText = source.getText().toString();
if(source.getClassName().equals("android.widget.TextView") && source.getParent()!=null && source.getParent().getClassName().equals("android.widget.FrameLayout") && source.getParent().getParent()==null){
return recivedText;
}
}
示例代码 2
if (source.getPackageName().equals("PACKAGE NAME OF APP FOR WHICH YOUR EXPECTING EVENT")) {
if(event.getEventType()==AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && "COMPLETE NAME OF ACTIVITY CLASS WITH PACKAGE NAME (if you want it for some specific screen)".equals(event.getClassName())){
if(source.getText()!=null && source.getClassName().equals("android.widget.TextView") && source.getParent()!=null && source.getParent().getClassName().equals("android.widget.RelativeLayout")&& source.getParent().getParent()!=null && source.getParent().getParent().getClassName().equals("android.widget.ScrollView") && source.getParent().getParent().getParent()!=null && source.getParent().getParent().getParent().getClassName().equals("android.support.v4.view.ViewPager")&& source.getParent().getParent().getParent().getParent()!=null && source.getParent().getParent().getParent().getParent().getClassName().equals("android.widget.FrameLayout")&& source.getParent().getParent().getParent().getParent().getParent()==null){
return source.getText().toString();
}
}
这有点笨拙,但要使其正常工作,您必须深入查看日志以找到将您带到所需数据的模式。
2017 年11 月 20 日更新
Google 将暂停所有使用辅助功能服务的应用程序,而不是辅助功能。我收到了一封关于我的一个应用程序的电子邮件,其他开发人员也收到了来自谷歌(Reddit)的相同电子邮件。所以,我认为我们应该寻找一些其他的做事方式,我请求你也请在这里更新它,如果有人提出其他实现来实现相同的行为,它也会帮助其他人。
谢谢 Umesh Chauhan