首页 » Software Engineering » 正文

Android的Android AccessibilityService 辅助服务

之前一直为一个在后台服务能否识别TP按键的处理而苦恼,后来通过AccessibilityService解决了。自己的服务是在后台用前置摄像头进行人眼识别,识别到人眼就保持LCD不灭,存在的一个问题是打开摄像头app偶尔会和后台的人眼识别open设备时起冲突,导致提示“无法连接相机”。后来一个处理思路是:当TP点击了,就屏蔽后台人眼识别的服务线程,而偏偏服务是没有界面的,是不可能接收到TP按键消息的,后来通过AccessibilityService绕了一层解决了问题。

(1)AccessibilityService类概述

当AccessibilityEvent事件被启动后AccessibilityService 会接收回调函数运行于后台,这些事件指的是在用户接口间的状态转换,比如:焦点变化,按钮被点击等。一些辅助服务继承于此类并且实现它的抽象方法,像这样的一个服务也必须在AndroidManifest.xml中被声明且被指定android.accessibilityservice.AccessibilityService的intent。

一个辅助服务的生命周期完全由系统管理,并遵循既定的服务生命周期。启动或者停止这个服务必须由明确的用户通过启用或停用来设定,在系统通过呼叫onServiceConnected()方法与服务绑定后,这个方法才能被想要执行装载的客户端所重载使用,一个辅助服务通过呼叫setServiceInfo(AccessibilityServiceInfo)方法来设定AccessibilityServiceInfo而配置。

(2)在设置的辅助功能界面中,可以启动或者停用具体的服务项目,这个是由系统支持的。这个服务需要像其他服务一样在AndroidManifest.xml文件中声明,但它也必须指定它处理“android.accessibilityservice.AccessibilityService”的意向,否则的话系统将会忽略这个服务。

(3)实例,完成启用这个辅助服务后,TP点击会发出人工的intent,在后台服务中用intentfilter来捕获这个tp消息,进行处理即可。

首先建立AccessibilityLite.java辅助服务文件,关键函数只有两个

package com.konkagene.smartstay;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.view.accessibility.AccessibilityEvent;
import android.content.Intent;
import android.util.Log;

public class AccessibilityLite extends AccessibilityService{
private static final String TAG = "FaceDetcting";
@Override
public void onAccessibilityEvent(AccessibilityEvent event) { //该函数定义辅助服务打开后操作响应的动作
// TODO Auto-generated method stub
Log.v(TAG,"onAccessibilityEvent send TOUCHED");
Intent localIntent = new Intent();
localIntent.setAction("com.konkagene.TOUCHED"); //发出TP被点击的广播,而TP点击这个EVENT类型是后一个函数制定的
sendBroadcast(localIntent);
}

public void onServiceConnected(){ //制定辅助服务完成的操作类型和参数
Log.v(TAG,"onServiceConnected");

AccessibilityServiceInfo i = new AccessibilityServiceInfo();
i.eventTypes = 4121;
i.feedbackType = 16;
i.notificationTimeout = 100; //以上三个参数完成响应TP的设定配置,该参数在指定的时间框架里得到每种类型的事件(去抖动)

setServiceInfo(i);
}
}

在工程的androidmanifest.xml中制定响应辅助服务的Intent,并制定处理文件

//绑定辅助服务

//启动辅助服务
之后,只需要在后台服务中捕获发出的com.konkagene.TOUCHED,就可以进行处理,就此完成了在service中捕获TP操作。如下:

IntentFilter ScreenFilter = new IntentFilter();
......
ScreenFilter.addAction("com.konkagene.TOUCHED");
registerReceiver(mScreenFilterReceiver, ScreenFilter);
.................

private BroadcastReceiver mScreenFilterReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent){
......................
else if(intent.getAction().equals("com.konkagene.TOUCHED")){
......................
对应处理,比如屏蔽人眼识别线程,避免摄像头冲突
}
}
};

参考原文:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=93359
参考原文:http://wikidroid.sinaapp.com/AccessibilityService