AccessibilityService辅助类用法(Android 中的另类钩子)

说在前面的话

为什么会把AccessibilityService叫做Android 中的另类钩子呢?搞过windows的都知道,钩子的含义就是能够监听到一切你想监听的内容,而Android中的AccessibilityService也可以监听到我们需要的某些功能。

用法

简介

AccessibilityService是一个辅助类,可以监听我们手机的焦点,窗口变化,按钮点击等等。实现它的服务需要在手机设置里面->辅助功能在这里面找到你自己实现的辅助类,然后打开它就可以进行我们一系列的监听了。

实例

现在我们要实现这样一个功能,当用户点击了安装包过后自动完成安装,因为在系统中,点击过安装包过后会弹出一个确认安装的选择界面。我们需要做的就是监听到安装的窗口弹出来过后就模拟用户点击确定操作,最后点击安装完成。这个过程j就需要用到我们的AccessibilityService来操作。

这里我先贴出代码然后慢慢的解释吧。首先我们还是新建一个类继承AccessibilityService。

public class WindowAccessibilitySeivice extends AccessibilityService
{
    final String    TAG             = WindowAccessibilitySeivice.class.getSimpleName();

    String          installPackge[] = { "com.android.packageinstaller" };

    @Override
    protected void onServiceConnected()
    {
        super.onServiceConnected();
        //可用代码配置当前Service的信息
        //      AccessibilityServiceInfo info = new AccessibilityServiceInfo();
        //      info.packageNames = installPackge; //监听过滤的包名
        //      info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; //监听哪些行为
        //      info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN; //反馈
        //      info.notificationTimeout = 100; //通知的时间
        //      setServiceInfo(info);
    }
    @SuppressLint("NewApi")
    private void findAndPerformAction(String text)
    {
        // 查找当前窗口中包含“安装”文字的按钮
        if(getRootInActiveWindow()==null)
            return;
        //通过文字找到当前的节点
        List<AccessibilityNodeInfo> nodes = getRootInActiveWindow().findAccessibilityNodeInfosByText(text);
        for (int i = 0; i < nodes.size(); i++)
        {
            AccessibilityNodeInfo node = nodes.get(i);
            // 执行按钮点击行为
            if (node.getClassName().equals("android.widget.Button")&&node.isEnabled())
            {
                node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
        }
    }
    @SuppressLint("NewApi")
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event)
    {
        if (event.getSource() != null)
        {
                findAndPerformAction("安装");
                findAndPerformAction("下一步");
                findAndPerformAction("完成");
        }
    }
    @Override
    public void onInterrupt()
    {
    }
}

onAccessibilityEvent

这里面最重要的部分就是onAccessibilityEvent这个回调函数,当我们注册了监听事件的时候,当有事件发生就会通知我们这个函数,但是一定要注意这个函数通知是异步的,当然很多朋友就会问这个是怎么通知到这里来的呢?他是通过AccessibilityDelegate这个代理类,发送出来的,这个类有个方法sendAccessibilityEvent可以发送事件。那这个类又怎么和我们的窗口联系呢?这里举个例子。比如我们的View类里面有个setAccessibilityDelegate这个方法,是不是这下一切都明了了呢?然后就是调用我们的find函数去当前节点里面找到我们需要的节点信息,通过模拟点击事件来安装我们的软件,当然如果是输入框也是可以模拟输入的哦。

onServiceConnected

在这个回调函数里面可以配置我们当前的Service的信息,可以看我上面的代码都写得很清楚。但是记得也可以在我们的xml里面配置我们的Service的信息,这里我也是在xml里面配置的信息。在我们的res文件夹下面新建一个文件夹xml然后在里面新建一个xml文件accessibility.xml。

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:canRetrieveWindowContent="true"
    android:description="@string/testaccessibility"
    android:packageNames="com.android.packageinstaller"
    android:notificationTimeout="100" />

这里需要提醒的是配置的时候packageNames这个就是你要监听的包名,这里我们需要监听的是安装的信息,所以包名就是com.android.packageinstaller,可以有多个用逗号隔开,accessibilityEventTypes这个是监听的事件。

记得配置我们的Service在Mainfiset清单里面。

   <service
            android:name="com.bobo.accessbility.WindowAccessibilitySeivice"
            android:description="@string/testaccessibility"
            android:label="accessibility"
            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>

写到这里基本上就可以安装和使用了。如果需要看更多的Demo可以看SDKdemo里面的com.example.android.apis.accessibility这个包下面的东西。

这里给出当前demo的下载地址传送门

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-23 12:54:14

AccessibilityService辅助类用法(Android 中的另类钩子)的相关文章

android中RadioGroup、RadioButton、Spinner、EditText用法详解(含示例截图和源代码)

为了保护版权.尊重原创,转载请注明出处:http://blog.csdn.net/u013149325/article/details/43237757,谢谢! 今天在项目中用到了android中常用的RadioGroup.RadioButton.Spinner.EditText等控件,在此介绍一下它们的用法,希望对需要的朋友有帮助. 一.RadioGroup和RadioButton的使用 RadioButton就是我们常见的单选按钮,一个RadioGroup可以包含多个单选按钮,但是每次只能选

Android中this的用法

关于Android中this的用法解释 问题由来 由于很多同学在学习Android时候没有对Java有很深的了解,很多人都会对代码中各种各样的this产生疑惑. 以<第一行代码Android>P37页,P43页代码为例: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first_layout); Button but

Android中常见Intent习惯用法-上篇(附源码下载)

Android中的Intent是一个非常重要的类,如果对Intent不是特别了解,可以参见博文<Android中Intent概述及使用>.如果对Intent Filter不是特别了解,可以参见博文<Android中Intent对象与Intent Filter过滤匹配过程详解>. 本文着重讲一下Android中一些常见的Intent的习惯用法,比如如何通过Intent发送短信.发送邮件.启动摄像机拍照录视频.设置闹铃.打开WIFI设置界面等等. 限于篇幅,本博文分为上下两篇,这是上篇

Android中Parcelable与Serializable接口用法

转自: Android中Parcelable接口用法 1. Parcelable接口 Interface for classes whose instances can be written to and restored from a Parcel. Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing

android中Handle类的用法

android中Handle类的用法 当我们在处理下载或是其他需要长时间执行的任务时,如果直接把处理函数放Activity的OnCreate或是OnStart中,会导致执行过程中整个Activity无响应,如果时间过长,程序还会挂掉.Handler就是把这些功能放到一个单独的线程里执行,与Activity互不影响. 当用户点击一个按钮时如果执行的是一个常耗时操作的话,处理不好会导致系统假死,用户体验很差,而Android则更进一步,如果任意一个Acitivity没有响应5秒钟以上就会被强制关闭,

三、android中Handle类的用法

当我们在处理下载或是其他需要长时间执行的任务时,如果直接把处理函数放Activity的OnCreate或是OnStart中,会导致执行过程中整个Activity无响应,如果时间过长,程序还会挂掉.Handler就是把这些功能放到一个单独的线程里执行,与Activity互不影响. 当用户点击一个按钮时如果执行的是一个常耗时操作的话,处理不好会导致系统假死,用户体验很差,而Android则更进一步,如果任意一个Acitivity没有响应5秒钟以上就会被强制关闭,因此我们需要另外起动一个线程来处理长耗

关于Android 中 raw的用法以及与assets 的的区别和共同点

一.raw与assets的区别及共同点 (1) res/raw和assets的相同点 两个目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制. (2) res/raw和assets的不同点: 1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.raw.filename: assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类. 2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是a

Android中的ContentValues用法

ContentValues 和HashTable类似都是一种存储的机制 但是两者最大的区别就在于,contenvalues只能存储基本类型的数据,像string,int之类的,不能存储对象这种东西,而HashTable却可以存储对象.ContentValues存储对象的时候,以(key,value)的形式来存储数据. 在忘数据库中插入数据的时候,首先应该有一个ContentValues的对象所以: ContentValues initial = new ContentValues(); init

Android中Toast的用法简介

转自:http://www.cnblogs.com/GnagWang/archive/2010/11/26/1888762.html Toast是Android中用来显示显示信息的一种机制,和Dialog不一样的是,Toast是没有焦点的,而且Toast显示的时间有限,过一定的时间就会自动消失.下面用一个实例来看看如何使用Toast. 1.默认效果 代码 Toast.makeText(getApplicationContext(), "默认Toast样式",     Toast.LEN