我试图总结我如何能够在博客文章中解决这个问题。任何需要帮助的人都可以看看它。
将无障碍服务提升到新的水平
我之前的答案被版主删除了,可能是因为我刚刚发布了一个博客链接。所以我再次发布我的答案,并在这里提供详细信息。
最简单的方法是由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() + "");
}
获取子计数
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();
}
}
它有点笨拙,但要让它工作,你必须深入研究日志,找到一个模式,将你带到你所需的数据。
更新 20/11/2017Google正在暂停所有使用无障碍服务的应用,以用于无障碍以外的其他用途。我收到了一封关于我的一个应用程序的电子邮件,其他开发人员也收到了来自谷歌(Reddit)的相同电子邮件。所以,我认为我们应该寻找一些其他的做事方式,我请求你也在这里更新它,如果有人想出其他实现来实现相同的行为,它也将帮助其他人。
谢谢乌梅什·乔汉