• UiAutomator2.0


    Accessibility:无障碍,又称辅助性功能.
    AccessibilityService:无障碍服务,继承于 Serveice. 它可以监听操作、检索窗口内容、启用触摸浏览等

    一、Android中的 Accessibility

    在原生android设备中 Settings 应用程序菜单中有一项 Accessibility(无障碍). 该项菜单下有项 TalkBack功能:它能读取屏幕上的内容,对于盲人和视力低弱人士而言,这项功能非常实用. 还有不知道大家是否会注意,使用三方app store批量自动安装app时,此时Accessibility中会出现 "xx自动安装"功能. 那么这些功能是怎实现的呢?是如何实现的呢?—— AccessibilityService

    二、UiAutomator2.0 与 AccessibilityService

      在《UiAutomator2.0 - 控件实现点击操作原理》中已经分析了UiAutomator自动测试点击操作的具体实现过程,最终的操作是由 UiAutomation 这个类实现的.从这个类注释可以看出:可以将UiAutomation看作特殊AccessibilityService 类型,它不为服务生命周期提供挂钩,并且公开了对UI测试自动化有用的其他API.也就是说UiAutomator2.0是通过 AccessibilityService来实现的.

    三、验证与 AccessibilityService的关联

    a.为了验证上面的猜想是否正确,在Android studio中新建app工程->建一个服务类MyAccessibility继承 AccessibilityService

    package com.zzw.barrierfree;
    
    import android.accessibilityservice.AccessibilityService;
    import android.accessibilityservice.AccessibilityServiceInfo;
    import android.util.Log;
    import android.view.accessibility.AccessibilityEvent;
    
    public class MyAccessibility extends AccessibilityService {
        private static final String TAG = MyAccessibility.class.getSimpleName();
    
        // 初始化服务操作
        @Override
        protected void onServiceConnected() {
            Log.d(TAG, "onServiceConnected: ------- config accessibility ");
            AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
            // 响应某个应用的事件,包名为应用的包名。设置为null等同于所有包名
            accessibilityServiceInfo.packageNames = new String[]{ "com.android.settings"};
            // 响应时间的类型,事件分很多种:单击、长按、滑动。 这里设置为所有事件
            accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
            // 设置回馈给用户的方式,语音播出还是振动
            accessibilityServiceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
            // 响应时间的设置
            accessibilityServiceInfo.notificationTimeout = 1000;
            setServiceInfo(accessibilityServiceInfo);
        }
    
        // 响应AccessibilityEvent的事件
        @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
            int eventTypeId = event.getEventType();
            String eventText = "";
            Log.d(TAG, "onAccessibilityEvent: ----------------Start--------------");
            switch (eventTypeId) {
                case AccessibilityEvent.TYPE_VIEW_CLICKED:
                    eventText = "TYPE_VIEW_CLICKED";
                    break;
                case AccessibilityEvent.TYPE_VIEW_FOCUSED:
                    eventText = "TYPE_VIEW_FOCUSED";
                    break;
                case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED:
                    eventText = "TYPE_VIEW_LONG_CLICKED";
                    break;
                case AccessibilityEvent.TYPE_VIEW_SELECTED:
                    eventText = "TYPE_VIEW_SELECTED";
                    break;
                case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
                    eventText = "TYPE_VIEW_TEXT_CHANGED";
                    break;
                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                    eventText = "TYPE_WINDOW_STATE_CHANGED";
                    break;
                case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                    eventText = "TYPE_NOTIFICATION_STATE_CHANGED";
                    break;
                case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:
                    eventText = "TYPE_TOUCH_EXPLORATION_GESTURE_END";
                    break;
                case AccessibilityEvent.TYPE_ANNOUNCEMENT:
                    eventText = "TYPE_ANNOUNCEMENT";
                    break;
                case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START:
                    eventText = "TYPE_TOUCH_EXPLORATION_GESTURE_START";
                    break;
                case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
                    eventText = "TYPE_VIEW_HOVER_ENTER";
                    break;
                case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
                    eventText = "TYPE_VIEW_HOVER_EXIT";
                    break;
                case AccessibilityEvent.TYPE_VIEW_SCROLLED:
                    eventText = "TYPE_VIEW_SCROLLED";
                    break;
                case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED:
                    eventText = "TYPE_VIEW_TEXT_SELECTION_CHANGED";
                    break;
                case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
                    eventText = "TYPE_WINDOW_CONTENT_CHANGED";
                    break;
            }
            eventText = eventText + ":" + eventTypeId;
            Log.e(TAG, "onAccessibilityEvent:"+ eventText);
            Log.d(TAG, "onAccessibilityEvent: -------------------End----------------");
        }
    
        // 打断获取事件的过程
        @Override
        public void onInterrupt() {
    
        }
    }
    

    b.在AndroidManifest.xml中配置服务

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.zzw.barrierfree">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:theme="@style/AppTheme.NoActionBar">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <!--服务配置-->
            <service
                android:name=".MyAccessibility"
                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
                <intent-filter>
                    <action android:name="android.accessibilityservice.AccessibilityService" />
                </intent-filter>
            </service>
        </application>
    </manifest>
    

    c.运行该app,此时在设置->无障碍中会出现配置的服务, 但是该服务处于关闭状态

    d.手动开启该服务,打开android studio中的logcat. 操作(点击/滑动等)设置应用程序,会出现相应的响应事件.以下是命令开启方式:
    adb shell settings put secure enabled_accessibility_services com.zzw.barrierfree/com.zzw.barrierfree.MyAccessibility
    adb shell settings put secure accessibility_enabled 1

    e.结合上篇的点击时监听的相应事件,与log中打印的事件是一致的. 那就说明:点击/滑动等操作是通过 AccessibilityService 监听对应的视图或窗口状态来判断操作是否成功执行.

  • 相关阅读:
    李开复给中国学生的第一封信
    vc++学习篇(三)——预处理命令之条件编译(#ifdef,#else,#endif,#if等)
    高级程序员考试时间安排和参考书推荐
    vc++学习篇(四)—— 指针
    程序员应具备的素质
    Word 2003 长篇文档排版技巧(二)
    Google 技巧集锦
    给中国学生的第二封信
    修复mysql表
    社保相关
  • 原文地址:https://www.cnblogs.com/zeo-to-one/p/10143279.html
Copyright © 2020-2023  润新知