android Accessibility service

来源:互联网 发布:1024最新地址知乎 编辑:程序博客网 时间:2024/05/11 03:40

偶然间看到了这篇文章,http://www.pingwest.com/kill-process-in-a-smart-way/,虽然对百度的产品没有太大的兴趣,但是它的超强加速功能还是挺吸引人的,就研究了一下。利用辅助功能服务模拟点击来实现的。

所以先要了解下辅助功能服务,Accessibility service.  网上关于AccessibilityService的阐述和用法已经很多很详细了,能翻墙且英文没问题就直接看官网:http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html,另外这个翻译的还不错,http://wiki.eoeandroid.com/Building_Accessibility_Services

在这里主要描述一下,“模拟点击”的实现原理。

首先要用到API 14添加的方法AccessibilityEvent.getSource()方法,API 18添加的AccessibilityNodeInfo.findAccessibilityNodeInfosByViewId()方法,AccessibilityNodeInfo.performAction()方法;

然后通过AccessibilityEvent.getSource()方法能够从资源中获得窗口的内容和行为,AccessibilityNodeInfo,通过findAccessibilityNodeInfosByViewId()方法可以确定我们要点击的按钮;

研究了源码找到了,Force stop对应的view id是R.id.left_button,findAccessibilityNodeInfosByViewId(“com.android.settings:id/left_button”);

确定了要点击的按钮之后,就要执行点击,AccessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)。

到这一步,我们已经实现了,点击"强制停止",但是点击“强制停止”之后,还会弹出一个让我们确认的dialog,所以还要点击确认。

同样确认按钮的view id是button1,但是不知道为什么用findAccessibilityNodeInfosByViewId()方法不能找到确认按钮,可能AlertDialog有些特殊。又废了一番周折,最后想到确认按钮在Dialog中的位置是固定的,所以通过AccessibilityEvent.getText().get(3),来获取确认按钮的text值,然后调用AccessibilityNodeInfo.findAccessibilityNodeInfosByText(String text),最后执行点击事件AccessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)。

下面是代码:

@SuppressLint("NewApi")private void processKillApplication(AccessibilityEvent event) {//Log.d("ATM", event.getEventType()+"++");if (event.getSource() != null) {if (event.getPackageName().equals("com.android.settings")) {List<AccessibilityNodeInfo> stop_nodes = event.getSource().findAccessibilityNodeInfosByViewId("com.android.settings:id/left_button");//Log.d("ATM", stop_nodes.toString());if (stop_nodes!=null && !stop_nodes.isEmpty()) {AccessibilityNodeInfo node;for(int i=0; i<stop_nodes.size(); i++){node = stop_nodes.get(i);if (node.getClassName().equals("android.widget.Button")) {if(node.isEnabled()){   node.performAction(AccessibilityNodeInfo.ACTION_CLICK);} else {performGlobalAction(GLOBAL_ACTION_BACK);}node.recycle();}}}List<AccessibilityNodeInfo> ok_nodes = null;if(event.getText() != null && event.getText().size() == 4) {ok_nodes = event.getSource().findAccessibilityNodeInfosByText(event.getText().get(3).toString());}if (ok_nodes!=null && !ok_nodes.isEmpty()) {AccessibilityNodeInfo node;for(int i=0; i<ok_nodes.size(); i++){node = ok_nodes.get(i);if (node.getClassName().equals("android.widget.Button")) {node.performAction(AccessibilityNodeInfo.ACTION_CLICK);Log.d("action", "click ok");}node.recycle();}}}}}


参考文章:http://www.tuicool.com/articles/bYRZJn

http://my.oschina.net/smalant/blog/41057


0 0