android Accessibility系统自带语音助手打开第三方应用

AccessibilityService是什么

某些用户由于视力、身体、年龄等问题致使他们不能使用触摸屏幕,为这些用户提供无障碍服务时应该更多的提供语音、触摸反馈、手势操作、模拟点击等。

为此android官方推出了AccessibilityService方便开发者为特殊用户服务。

更详细资料可以看android官方文档

AccessibilityService能做什么

AccessibilityService是一个辅助类,可以监听我们手机的焦点,窗口变化,按钮点击等,同时它还可以模拟点击。基本上等同于可以监听一切你想监听的内容。

如何使用AccessibilityService

AccessibilityService使用很简单:

1. 新建一个类继承AccessibilityService,并实现几个重要的重载方法;

2.在AndroidManifest中注册服务

3.配置AceessibilityService

通过这三步就可以创建自己的辅助类了,在 系统设置-》辅助功能中开启我们的服务就实现我们想要的功能了。


我们以利用系统自带语音助手打开第三方应用为例来实现。

1.新建MyAccessibilityService类并继承AccessibilityService

利用getRootInActivityWindow()方法可以获得当前界面的根节点node

然后通过findAccessibilityNodeInfosByText() 获取到我们想要的节点

public class MyAccessbilityService extends AccessibilityService {

    private static final String TAG = "MyAccessbilityService";
    //记录上一次识别结果,防止死循环
    private String lastText = "";
    /**
     * 连接服务成功后调用
     * 可选
     */
    protected void onServiceConnected() {

        Log.d(TAG, "onServiceConnected: success");
        super.onServiceConnected();

    }

    /**
     * 接受系统发来的accessibilityEvent
     * 必须实现
     */
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {

        AccessibilityNodeInfo nodes = getRootInActiveWindow();
        if (nodes == null){
            return;
        }
//        List nodeList =
//                nodes.findAccessibilityNodeInfosByViewId(Config.viewId);
        //  也可通过findAccessibilityNodeInfosByViewId 方式解决
        List nodeInfoList =
                nodes.findAccessibilityNodeInfosByText("芝麻开门");
            for (int i = 0; i < nodeInfoList.size(); i++){

                String text = nodeInfoList.get(i).getText().toString();
                Log.d(TAG, "onAccessibilityEvent: result" + i +" = " + text);

                if (!text.equals(lastText)){
                    dealText(text);
                }
            }
        nodes.recycle();
        Log.d(TAG, "onAccessibilityEvent: packageName = " + event.getPackageName());
        Log.d(TAG, "onAccessibilityEvent: eventType   = " + event.getEventType());
        Log.d(TAG, "onAccessibilityEvent: windowId    = " + event.getWindowId());
        Log.d(TAG, "onAccessibilityEvent: -------------");
    }
    /**
     * 中断服务
     * 必须实现
     */
    @Override
    public void onInterrupt() {
    }

    /**
     * 系统关闭服务时调用
     * 可选
     * @param intent
     * @return
     */
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    /**
     * 打开第三方应用,这里以打开我们自己的Activity为例
     * @param text 打开应用附带的消息
     */
    private void openApp(String text){
        Log.d(TAG, "open some app");
        lastText = text;
        Intent intent = new Intent(MyAccessbilityService.this, MainActivity.class);
        intent.putExtra("str",text);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
    /**
     * 处理语音识别结果
     * @param str
     */
    private void dealText(String str){
        if (str.contains(Config.mark)){
            openApp(str);
        }
    }
}
AccessibilityService中的重要方法

onServiceConnected() - 可选。系统会在成功连接上你的服务的时候调用这个方法,在这个方法里你可以做一下初始化工作,例如设备的声音震动管理,也可以调用setServiceInfo()进行配置工作。

onAccessibilityEvent() - 必须。通过这个函数可以接收系统发送来的AccessibilityEvent,接收来的AccessibilityEvent是经过过滤的,过滤是在配置工作时设置的。

onInterrupt() - 必须。这个在系统想要中断AccessibilityService返给的响应时会调用。在整个生命周期里会被调用多次。

onUnbind() - 可选。在系统将要关闭这个AccessibilityService会被调用。在这个方法中进行一些释放资源的工作。


2.在AndroidManifest中注册服务

在AndroidManifest下application标签中加入如下代码

        
            
                
            
            
        

label           为服务的名字

description 为服务的描述

这样我们的服务就成功注册了


3.配置AceessibilityService

有两种配置方式,一种是java代码配置,一种是使用xml文件配置。xml配置方式支持更多的参数,推荐使用这种方式配置。

xml文件配置方式

在res文件夹下新建一个xml文件夹

在xml文件夹中新建一个xml文件,取名跟meta-data中的name一致

android Accessibility系统自带语音助手打开第三方应用_第1张图片

xml文件代码



packageNames中填入想要监听的包名,我的测试机是魅族MX3,语音助手的包名是com.meizu.voiceassistant ,可以替换成你需要的包名


java代码配置方式

需要new一个AccessibilityServiceInfo对象并设置相关参数

最后在MyaccessibilityService类中的onServiceConnected方法中配置参数。

在MyaccessibilityService中添加方法

    private void setServiceInfo(int feedbackType) {
        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
        // We are interested in all types of accessibility events.
        info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
        // We want to provide specific type of feedback.
        info.feedbackType = feedbackType;
        // We want to receive events in a certain interval.
        info.notificationTimeout = EVENT_NOTIFICATION_TIMEOUT_MILLIS;
        // We want to receive accessibility events only from certain packages.
        info.packageNames = PACKAGE_NAMES;
        setServiceInfo(info);
    }
在onServiceConnect中调用该方法

    protected void onServiceConnected() {
        super.onServiceConnected();
        setServiceInfo(AccessibilityServiceInfo.FEEDBACK_GENERIC);
    }



经过以上三步我们的服务就编写完成了

编译运行就可以在    系统设置->辅助功能   中看到我们 的服务

android Accessibility系统自带语音助手打开第三方应用_第2张图片



打开服务,启动系统自带的语音助手,说出密令词 “芝麻开门”

就可以打开MainActivity了。


利用系统自带语音助手打开第三方应用就实现了。



你可能感兴趣的:(Android)