【问题标题】:Get text content of the android screen获取android屏幕的文本内容
【发布时间】:2015-06-18 08:14:41
【问题描述】:

有什么方法可以获取安卓手机屏幕上显示的文字内容。它可以是任何安卓应用程序。

例如在上面链接的图像中,我希望获取图像中的所有文本(从“Larry Page”到结尾“Fred Smith”以及屏幕上所有单词的位置)及其在屏幕上的相应位置。

【问题讨论】:

  • 这些文字在您的应用中吗?
  • @phuc_tran 似乎想从任何 Android 应用中抓取文本。
  • 不,文本不会来自我的应用程序,我想获取任何应用程序在移动屏幕上显示的所有文本。
  • 您找到解决方案了吗?
  • 不过,这个应用程序的表现如何! play.google.com/store/apps/…

标签: android android-intent android-screen-support


【解决方案1】:

这可以使用 Android 的辅助功能来实现(就像通用复制应用一样)。

你需要做的是实现一个名为AccessabilityService的类 它可以通过监听器访问所有屏幕 UI。

为此,您需要在清单中声明它:

 <service android:name=".MyAccessibilityService">
 <intent-filter>
     <action android:name="android.accessibilityservice.AccessibilityService" />
 </intent-filter>
 <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" />

@xml/accessibilityservice 文件是你配置服务的地方,比如要监听哪个包或你想获得什么样的事件:

<accessibility-service
 android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
 android:packageNames="com.example.android.myFirstApp, com.example.android.mySecondApp"
 android:accessibilityFeedbackType="feedbackSpoken"
 android:notificationTimeout="100"
 android:settingsActivity="com.example.android.apis.accessibility.TestBackActivity"
 android:canRetrieveWindowContent="true"/>

在类中重写方法:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    Log.v(TAG, String.format(
            "onAccessibilityEvent: type = [ %s ], class = [ %s ], package = [ %s ], time = [ %s ], text = [ %s ]",
            getEventType(event), event.getClassName(), event.getPackageName(),
            event.getEventTime(), getEventText(event)));
}

在该方法中,您应该在 UI 中找到所需的文本/TextView/EditText 并从中提取所需的文本。

注意:这种方式需要只有用户可以授予您的辅助功能权限,并且不能在运行时完成。

您可以在 Android 文档中了解更多关于how to implement an AccessabilityService的信息

编辑:在评论中的问题之后,我添加了从屏幕中所有文本组件中读取的代码:

    private void printAllViews(AccessibilityNodeInfo mNodeInfo) {
        if (mNodeInfo == null) return;
        String log ="";
        for (int i = 0; i < mDebugDepth; i++) {
            log += ".";
        }
        log+="("+mNodeInfo.getText() +" <-- "+ 
        mNodeInfo.getViewIdResourceName()+")";
        Log.d(TAG, log);
        if (mNodeInfo.getChildCount() < 1) return;
        mDebugDepth++;

        for (int i = 0; i < mNodeInfo.getChildCount(); i++) {
            printAllViews(mNodeInfo.getChild(i));
        }
        mDebugDepth--;
    }

别忘了像这样初始化 AccessibilityNodeInfo 和深度计数器:

public void onAccessibilityEvent(AccessibilityEvent event) {
    mDebugDepth = 0; 
    mNodeInfo = event.getSource();
    printAllViews(mNodeInfo);
 ...
}

【讨论】:

  • 你好。我尝试像您一样登录,但无法在屏幕上显示任何文本。你能分享更多关于你的工作吗?谢谢。
  • 见编辑部分。
  • 我需要手动创建无障碍服务 xml 吗?在哪个文件夹中?
  • 是的,您需要手动创建该文件。路径是:/app/src/main/res/xml/accessibilityservice.xml
  • 你为什么使用mDebugDepth?还有什么需要注意的,而不仅仅是记录?因为有时我在 10 次通话后得到 java.lang.StackOverflowError: stack size 8MB printAllViews() ~ mDebugDepth == 10 ?!
【解决方案2】:

这可以通过使用“uiautomatorviewer”来完成。这个 bin 文件可以在 Android SDK/tools/bin/ 文件夹中找到。

在终端中运行 uiautomatorviewer。

$./uiautomatorviewer
  • 确保 USB 调试已启用并将设备连接到 PC。
  • 点击 uiautomator 转储按钮
  • 点击文字,可以从侧面的“节点详情”复制文字。

如果是 webview,上述方法可能不起作用。

如果您想以编程方式执行此操作,请查看android.getText() 方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 2021-11-14
    • 2011-03-05
    • 1970-01-01
    相关资源
    最近更新 更多