Android:使用辅助功能服务阅读Google Chrome网址

时间:2016-08-05 07:07:49

标签: android google-chrome accessibilityservice

我想阅读用户在浏览器中输入的网址。这是我的辅助功能服务代码。

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFlags="flagDefault"
android:accessibilityEventTypes="typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="0"
android:canRetrieveWindowContent="true"
android:packageNames="com.android.chrome"
android:description="@string/accessibility_description"
/>

在AndroidManifest中

<service android:name=".MyAccessibilityService"
        android:label="@string/accessibility_title"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService"/>
        </intent-filter>
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibility_service_config" />
    </service>

在MyAccessibilityService

 public void onAccessibilityEvent(AccessibilityEvent event) {
    debug("On accessibility event");
    getChromeUrl(getRootInActiveWindow());
}

public void getChromeUrl(AccessibilityNodeInfo nodeInfo) {
    //Use the node info tree to identify the proper content.
    //For now we'll just log it to logcat.
    Log.d(TAG, toStringHierarchy(nodeInfo, 0));
}
private String toStringHierarchy(AccessibilityNodeInfo info, int depth) {
    if (info == null) return "";

    String result = "|";
    for (int i = 0; i < depth; i++) {
        if (result.contains("http")) {
            Log.d(TAG, "Found URL!!!!!!!!!!!!!!" + result);
        }
        result += "  ";
    }

    result += info.toString();

    for (int i = 0; i < info.getChildCount(); i++) {
        result += "\n" + toStringHierarchy(info.getChild(i), depth + 1);
    }

    return result;
}
private static void debug(Object object) {
    Log.d(TAG, object.toString());
}

问题是我从rootview中的url中的内容获取视图,而不是顶部地址栏。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:1)

我用

android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews|flagRequestTouchExplorationMode|flagRequestEnhancedWebAccessibility|flagReportViewIds|flagRetrieveInteractiveWindows"

我听Windows Changed Event

public void onAccessibilityEvent(AccessibilityEvent event) {
    if(AccessibilityEvent.eventTypeToString(event.getEventType()).contains("WINDOW")){
         AccessibilityNodeInfo nodeInfo = event.getSource();
         dfs(nodeInfo);
    }
}

public void dfs(AccessibilityNodeInfo info){
    if(info == null)
        return;
    if(info.getText() != null && info.getText().length() > 0)
        System.out.println(info.getText() + " class: "+info.getClassName());
    for(int i=0;i<info.getChildCount();i++){
       AccessibilityNodeInfo child = info.getChild(i);
       dfs(child);
       if(child != null){
          child.recycle();
       }
    }
}

它有效!

答案 1 :(得分:0)

嗯。您的代码或多或少对我有用(尽管我使用了不同的accessibility_service_config.xml设置,请参见下文..),只要Chrome处于活动状态并且地址栏实际显示 - 我已注意到一个问题一旦您开始与该网页进行互动,Chrome就会自动隐藏地址栏,而且我无法找到一种方法从Chrome获取网址。出于调试/开发目的,直到找到最适合您的解决方案,您可能希望将一些accessibility_service_config.xml设置更改为更一般,确保启动此项目并获取可能的所有可访问性事件......这就是我正在使用的内容:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:notificationTimeout="0"
    android:canRetrieveWindowContent="true"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
    android:canRequestFilterKeyEvents="true" />

差异是

  1. 省略&#34; android:packageNames&#34; label(使其默认为&#34; all&#34;)

  2. 使用android的最常用设置:accessibilityEventTypes和android:accessibilityFeedbackType(不确定,但你使用&#34; typeWindowStateChanged&#34;对于android:accessibilityEventTypes可能是你问题的一部分?)

  3. 添加android:canRequestFilterKeyEvents =&#34; true&#34;

  4. 祝你好运。

答案 2 :(得分:-1)

可以使用以下代码以编程方式更改URL。

AccessibilityNodeInfo source = accessibilityEvent.getSource();
            if (source != null & 
"android.widget.EditText".equals(accessibilityEvent.getClassName())) {
                Bundle arguments = new Bundle();

                String typedDetails = source.getText().toString();

                Log.d("typed text", source.getText().toString());

                if (typedDetails.contains("facebook")) {
                    //showOverlay();
//                    }
                    arguments.putCharSequence(AccessibilityNodeInfo
                            .ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, 
"file:///android_asset/redirect.html");
                    final AccessibilityNodeInfo clickableParent = 
source.getParent();

                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

source.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);

source.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }

使用AccessibilityNodeInfo.ACTION_SET_TEXT 我也尝试执行点击,如下面的代码中所示 AccessibilityNodeInfo.ACTION_CLICK但它不起作用。想知道是否有可能做到这一点? 感谢