辅助功能是Android系统提供的一种服务,派生自Service类。这个服务提供了增强的用户界面,目的是为了帮助残障人士。它一般提供了页面元素查找功能和元素点击功能。
通过辅助功能,开发者可以实现一些非常丰富的功能:抢红包微信自动回复检查微信好友进程清理判断应用当前状态防卸载浏览器劫持跳过用户授权
关于更多AccessibilityService的安全信息可以查看这篇文章:
AccessibilityService(辅助功能类)派生自Service,它是一个服务类。AccessibilityService是一个抽象类,所以要使用辅助功能的话,就要从AccessibilityService类派生一个实例类,完成配置、监听,再根据监听到的元素完成各种动作。例如,下面这个案例:MainActivity.javaimport android.app.Activity;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.provider.Settings;import android.text.TextUtils;import android.util.Log;import com.example.accessibilityservicetest.R;public class MainActivity extends Activity { private static String TAG="test"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //如果没开启,就提醒开启辅助功能 if(!isAccessibilitySettingsOn(this)){ Intent intent=new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS); startActivity(intent); } } //判断是否开启辅助功能 private boolean isAccessibilitySettingsOn(Context mContext) { int accessibilityEnabled = 0; final String service = getPackageName() + "/" + MyCustomAccessibilityService.class.getCanonicalName(); try { accessibilityEnabled = Settings.Secure.getInt( mContext.getApplicationContext().getContentResolver(), android.provider.Settings.Secure.ACCESSIBILITY_ENABLED); Log.v(TAG, "accessibilityEnabled = " + accessibilityEnabled); } catch (Settings.SettingNotFoundException e) { Log.e(TAG, "Error finding setting, default accessibility to not found: " + e.getMessage()); } TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':'); if (accessibilityEnabled == 1) { Log.v(TAG, "***ACCESSIBILITY IS ENABLED*** -----------------"); String settingValue = Settings.Secure.getString( mContext.getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); if (settingValue != null) { mStringColonSplitter.setString(settingValue); while (mStringColonSplitter.hasNext()) { String accessibilityService = mStringColonSplitter.next(); Log.v(TAG, "-------------- > accessibilityService :: " + accessibilityService + " " + service); if (accessibilityService.equalsIgnoreCase(service)) { Log.v(TAG, "We've found the correct setting - accessibility is switched on!"); return true; } } } } else { Log.v(TAG, "***ACCESSIBILITY IS DISABLED***"); } return false; }}
MyCustomAccessibilityService.java
public class MyCustomAccessibilityService extends AccessibilityService { //该方法在初始化辅助功能时调用 @Override protected void onServiceConnected() { super.onServiceConnected(); } //获取到指定的监听事件 @Override public void onAccessibilityEvent(AccessibilityEvent event) { //辅助功能的时间类型 int eventType=event.getEventType(); //输出事件的字符串type String typeStr=event.eventTypeToString(eventType); //根据事件类型来分发我们需要的操作,这里以窗口变化为例 if(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED==eventType){ //判断我们的辅助功能,是否在约定的界面执行,以设置界面为例 if("com.android.settings".equals(event.getPackageName())){ //doSometing } }else if(AccessibilityEvent.TYPE_GESTURE_DETECTION_START==eventType){ }else{ //在完成自己的操作时候,可以关闭自己的服务,下次使用再开启 //API>=24 //disableSelf() } //通过event遍历nodeInfo AccessibilityNodeInfo info= event.getSource(); //findFocus(int) //getWindows() //getRootInActiveWindow() //遍历节点 for(int i=0;ilist = childNode.findAccessibilityNodeInfosByViewId("com.android" +".settings:id/xxxx"); // 通过text查找 //List list = info.findAccessibilityNodeInfosByText("xxxx"); Log.i("InfoType",childNode.getClassName().toString()); Log.i("InfoText", childNode.getText().toString()); Log.i("InfoPkgName",childNode.getPackageName().toString()); Log.i("InfoViewId", childNode.getViewIdResourceName()); //进行点击操作 for(AccessibilityNodeInfo anodeinfo : list){ if(anodeinfo.isClickable()){ anodeinfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } } } //辅助功能被中断时候调用该方法 @Override public void onInterrupt() { }}
acessibilityserviceconfig.xml
AndroidManifest.xml
可以通过DDMS来查看手机界面的节点元素的各种信息:
原文链接: