在Android中使用辅助功能服务获取活动的布局名称

时间:2017-08-18 07:28:08

标签: android android-layout accessibilityservice android-accessibility

我正在尝试创建一个应用来获取其他应用的包名称,活动名称和活动布局名称(XML)。为此,我使用辅助功能服务来获取前景窗口的WINDOW_STATE_CHANGED。

我取得了什么?

我可以使用辅助功能服务获取其他应用的包名称和活动名称。

我无法实现的目标!

我已经尝试了几乎所有可能的解决方案来获取Activity的布局名称,但不幸的是我每次连续尝试都失败了。

到目前为止我尝试了什么:

第1步:

res / xml 文件夹下创建 accessibilityservice.xml ,如下所示

<accessibility-service
    xmlns:tools="http://schemas.android.com/tools"
    android:accessibilityEventTypes="typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagIncludeNotImportantViews"
    android:canRetrieveWindowContent="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:ignore="UnusedAttribute"/>

第2步:

创建 WindowChangeDetectingService.java 服务类并记录包名称和活动,如下所示

    import android.accessibilityservice.AccessibilityService;
    import android.accessibilityservice.AccessibilityServiceInfo;
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.pm.ActivityInfo;
    import android.content.pm.PackageManager;
    import android.os.Build;
    import android.util.Log;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.accessibility.AccessibilityEvent;
    import android.view.accessibility.AccessibilityNodeInfo;

    import java.util.List;

    public class WindowChangeDetectingService extends AccessibilityService {

        @Override
        protected void onServiceConnected() {
            super.onServiceConnected();

            //Configure these here for compatibility with API 13 and below.
            AccessibilityServiceInfo config = new AccessibilityServiceInfo();
            config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
            config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;

            if (Build.VERSION.SDK_INT >= 16)
                //Just in case this helps
                config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;

            setServiceInfo(config);
        }

        @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {

            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                if (event.getPackageName() != null && event.getClassName() != null) {
                    ComponentName componentName = new ComponentName(
                        event.getPackageName().toString(),
                        event.getClassName().toString()

                    );


                    Log.i("AccessPackagename",  event.getPackageName().toString());
                    Log.i("AccessgetClassName",  event.getClassName().toString());

                }
            }
        }
}

步骤3:在manifest.xml中创建已注册的WindowChangeDetectingService,如下所示

<service
            android:name=".WindowChangeDetectingService"
            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/accessibilityservice"/>
        </service>

OUTPUT :(从Logcat检索)

08-18 12:51:45.430 11206-11206/com.takeoffandroid.screenlog I/AccessPackagename: com.takeoffandroid.screenlog
08-18 12:51:45.430 11206-11206/com.takeoffandroid.screenlog I/AccessgetClassName: com.takeoffandroid.screenlog.MainActivity

我的要求:(预期输出)

08-18 12:51:45.430 11206-11206/com.takeoffandroid.screenlog I/AccessPackagename: com.takeoffandroid.screenlog
    08-18 12:51:45.430 11206-11206/com.takeoffandroid.screenlog I/AccessgetClassName: com.takeoffandroid.screenlog.MainActivity

--------------------------------------------------------------------    --------------------------------------------------------------------

    08-18 12:51:45.430 11206-11206/com.takeoffandroid.screenlog I/AccessgetLayoutName: activity_main.xml //Should be capable to read the layout name of the MainActivity

--------------------------------------------------------------------   --------------------------------------------------------------------

我过去两天一直在研究这个要求,但是在Android中使用辅助功能服务无法找到任何方法或方法。任何帮助或建议对我都很有帮助。提前致谢。

1 个答案:

答案 0 :(得分:1)

您需要修改服务配置,以在您的辅助功能节点信息中包含视图ID名称。

<accessibility-service
xmlns:tools="http://schemas.android.com/tools"
android:accessibilityEventTypes="typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagReportViewIds|flagIncludeNotImportantViews"
android:canRetrieveWindowContent="true"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="UnusedAttribute"/>

这里的重要变化是:

  

机器人:accessibilityFlags = “flagReportViewIds | flagIncludeNotImportantViews”

或甚至更具体地说这部分:

  

flagReportViewIds

此外,您不应包含onServiceConnected功能。您正在修改您在service_config xml文件中执行的所有配置。你也没有正确地做到这一点。创建新的服务信息很危险,因为您不太可能填充所有重要的字段。这一行:

AccessibilityServiceInfo config = new AccessibilityServiceInfo();

应该是这样的:

AccessibilityServiceInfo config = getServiceInfo()

然后修改它!虽然,严肃地说,不要这样做,只需依靠service_config XML道具。

一旦你有正确的配置,你应该能够这样做:

someAccessibilityNodeInfo.getViewIdResourceName()

您要查找的是哪个ID。