android AccessibilityService的学习和应用
来源:互联网 发布:mysql linux登陆命令 编辑:程序博客网 时间:2024/06/14 12:03
最近公司要用钉钉作为打卡工具,说好的弹性上班呢,于是乎想找个破解方法,百度了一圈,有个大神的文章可以解决此问题,文章地址:
http://blog.csdn.net/fenzzz/article/details/50156697 点击打开链接
原来和微信抢红包一样里面用到了一个非常关键的类 AccessibilityService,这个类的作用就是监听屏幕发生各种改变事件,比如手机打开红包页面,当一旦出现红包就自动去模拟点击红包,肯定比人为速度更快,那么钉钉打卡一样的原理,比如早上9点设置一个定时器或者给安卓了钉钉的手机打个电话神马的,然后去触发打开钉钉,然后检测到页面相应的变化去处理,一步一步的就可以到打卡页面打卡了,这里贴下根据大神的代码稍微改动了一点点,
代码很简单,稍微看一下就能明白其中原理。
这里主要用到了3个知识点,
一、根据包名打开APP
import java.util.List;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.content.pm.PackageManager.NameNotFoundException;import android.content.pm.ResolveInfo;public class Utils { public static void openCLD(String packageName,Context context) { PackageManager packageManager = context.getPackageManager(); PackageInfo pi = null; try { pi = packageManager.getPackageInfo("com.alibaba.android.rimet", 0); } catch (NameNotFoundException e) { } Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); resolveIntent.setPackage(pi.packageName); List<ResolveInfo> apps = packageManager.queryIntentActivities(resolveIntent, 0); ResolveInfo ri = apps.iterator().next(); if (ri != null ) { String className = ri.activityInfo.name; Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ComponentName cn = new ComponentName(packageName, className); intent.setComponent(cn); context.startActivity(intent); } }}二、注册一个广播接受者,用于接受电话短信之类的广播
import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.telephony.TelephonyManager;import android.app.Service;import android.util.Log;public class PhoneReceiver extends BroadcastReceiver { private static final String TAG = "message"; private static boolean mIncomingFlag = false; private static String mIncomingNumber = null; @Override public void onReceive(Context context, Intent intent) { // 如果是拨打电话 if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { mIncomingFlag = false; String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); Log.i(TAG, "call OUT:" + phoneNumber); } else { // 如果是来电 TelephonyManager tManager = (TelephonyManager) context .getSystemService(Service.TELEPHONY_SERVICE); switch (tManager.getCallState()) { case TelephonyManager.CALL_STATE_RINGING: mIncomingNumber = intent.getStringExtra("incoming_number"); Log.i(TAG, "RINGING :" + mIncomingNumber); if(mIncomingNumber!=null&&mIncomingNumber.equals("15606708596")){ Utils.openCLD("com.alibaba.android.rimet", context); DingService.instance.setServiceEnable(); } break; case TelephonyManager.CALL_STATE_OFFHOOK: if (mIncomingFlag) { Log.i(TAG, "incoming ACCEPT :" + mIncomingNumber); } break; case TelephonyManager.CALL_STATE_IDLE: if (mIncomingFlag) { Log.i(TAG, "incoming IDLE"); } break; } } }}三、重点,继承AccessibilityService,重写@Override
public void onAccessibilityEvent(AccessibilityEvent event);event包含了整个屏幕变化的监听事件,可以根据这些事件来处理自己想要的操作
import java.util.ArrayList;import java.util.List;import android.accessibilityservice.AccessibilityService;import android.util.Log;import android.view.accessibility.AccessibilityEvent;import android.view.accessibility.AccessibilityNodeInfo;import android.widget.Toast;public class DingService extends AccessibilityService {private String TAG = getClass().getSimpleName();private boolean isFinish = false;public static DingService instance;private int index = 1;/** * 获取到短信通知 * 0.唤醒屏幕 * 1.打开钉钉 * 2.确保当前页是主页界面 * 3.找到“工作”tab并且点击 * 4.确保到达签到页面 * 5.找到签到按钮,并且点击 * 6.判断签到是否成功 * 1.成功,退出程序 * 2.失败,返回到主页,重新从1开始签到 */@Overridepublic void onAccessibilityEvent(AccessibilityEvent event) {// TODO Auto-generated method stub// final int eventType = event.getEventType();ArrayList<String> texts = new ArrayList<String>();Log.i(TAG, "事件---->" + event.getEventType());if(isFinish){return;}AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();if(nodeInfo == null) {Log.w(TAG, "rootWindow为空");return ;}// nodeInfo.// System.out.println("nodeInfo"+nodeInfo);System.out.println("index:"+index);switch (index) {case 1: //进入主页OpenHome(event.getEventType(),nodeInfo);break;case 2: //进入签到页OpenQianDao(event.getEventType(),nodeInfo);break;case 3:doQianDao(event.getEventType(),nodeInfo);break;default:break;}}private ArrayList<String> getTextList(AccessibilityNodeInfo node,ArrayList<String> textList){if(node == null) {Log.w(TAG, "rootWindow为空");return null;}if(textList==null){textList = new ArrayList<String>();}String text = node.getText().toString();if(text!=null&&text.equals("")){textList.add(text);}// node.getreturn null;}private void OpenHome(int type,AccessibilityNodeInfo nodeInfo) {if(type == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){//判断当前是否是钉钉主页List<AccessibilityNodeInfo> homeList = nodeInfo.findAccessibilityNodeInfosByText("成长");if(!homeList.isEmpty()){//点击boolean isHome = click( "成长");System.out.println("---->"+isHome);index = 2;System.out.println("点击进入主页签到");Log.d(TAG, "点击进入主页签到");}}}private void OpenQianDao(int type,AccessibilityNodeInfo nodeInfo) {if(type == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED){//判断当前是否是主页的签到页List<AccessibilityNodeInfo> qianList = nodeInfo.findAccessibilityNodeInfosByText("考勤打卡");if(!qianList.isEmpty()){boolean ret = click( "考勤打卡");index = 3;System.out.println("点击进入签到页面详情");Log.d(TAG, "点击进入点击进入签到页面详情");}// index = ret?3:1;}}private void doQianDao(int type,AccessibilityNodeInfo nodeInfo) {if(type == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED){//判断当前页是否是签到页List<AccessibilityNodeInfo> case1 = nodeInfo.findAccessibilityNodeInfosByText("上班时间");//if(!case1.isEmpty()){//click("开启我的签到之旅");//System.out.println("点击签到之旅");//}List<AccessibilityNodeInfo> case2 = nodeInfo.findAccessibilityNodeInfosByText("下班时间");//if(!case2.isEmpty()){//click("我知道了");//System.out.println("点击我知道对话框");//}List<AccessibilityNodeInfo> case3 = nodeInfo.findAccessibilityNodeInfosByText("更新打卡>");Log.d(TAG, "case1 " + case1 + "case2 " + case2 + "case3 " + case3);if(!case1.isEmpty() && !case2.isEmpty() && !case3.isEmpty()){Toast.makeText(getApplicationContext(), "发现目标啦!!~~", Toast.LENGTH_SHORT).show();System.out.println("发现目标啦!");Log.d(TAG, "发现目标啦!");click("更新打卡>");isFinish = true;}}//if(type == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){//List<AccessibilityNodeInfo> case3 = nodeInfo.findAccessibilityNodeInfosByText("签到");//if(!case3.isEmpty()){//Toast.makeText(getApplicationContext(), "发现目标啦!!~~", 1).show();//}//}}//通过文字点击private boolean click(String viewText){AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();if(nodeInfo == null) {Log.w(TAG, "点击失败,rootWindow为空");return false;}List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText(viewText);if(list.isEmpty()){//没有该文字的控件Log.w(TAG, "点击失败,"+viewText+"控件列表为空");return false;}else{//有该控件//找到可点击的父控件AccessibilityNodeInfo view = list.get(0);return onclick(view); //遍历点击}}private boolean onclick(AccessibilityNodeInfo view){if(view.isClickable()){view.performAction(AccessibilityNodeInfo.ACTION_CLICK);Log.w(TAG, "点击成功");return true;}else{AccessibilityNodeInfo parent = view.getParent();if(parent==null){return false;}onclick(parent);}return false;}//点击返回按钮事件private void back(){performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);}@Overridepublic void onInterrupt() {// TODO Auto-generated method stub}@Overrideprotected void onServiceConnected() {// TODO Auto-generated method stubsuper.onServiceConnected();Log.i(TAG, "service connected!");Toast.makeText(getApplicationContext(), "连接成功!", Toast.LENGTH_SHORT).show();instance = this;}public void setServiceEnable(){isFinish = false;Toast.makeText(getApplicationContext(), "服务可用开启!", Toast.LENGTH_SHORT).show();index = 1;}}
注意:运行安装好这个项目后,以华为手机为例,须要在手机设置——高级设置——辅助功能找个这个APP然后开启AccessibilityService这个服务,不然运行了程序会报空指针,说AccessibilityService为空。
好了,又可以愉快玩耍了
钉钉打卡项目地址:http://download.csdn.net/download/msn465780/10017453 点击打开链接
阅读全文
0 0
- android AccessibilityService的学习和应用
- android AccessibilityService的用法
- Android 探究AccessibilityService的秘密
- android 使用AccessibilityService 自动安装应用
- Android AccessibilityService 应用之微信抢红包外挂
- android 使用AccessibilityService 自动安装应用
- Android系统学习-android.accessibilityservice(辅助服务)
- Accessibilityservice学习
- Android AccessibilityService(辅助服务)学习
- android-AccessibilityService
- Android AccessibilityService
- AccessibilityService的学习,抢红包实现
- Android开发中AccessibilityService的使用
- Android开发中AccessibilityService的使用
- Android 源码阅读第一编 AccessibilityServic包下的AccessibilityService 和 AccessibilityServiceInfo<meta-data
- [Android进阶]学习AccessibilityService实现微信抢红包插件
- Android开发自动话操作Accessibilityservice和adb结合
- android.accessibilityservice包介绍
- ARC078
- 昂昂
- 云数据库管理与数据迁移可以认证了,是时候证明自己了
- C# 索引器
- 第七周 【项目1-建立顺序环形队列算法库】
- android AccessibilityService的学习和应用
- [学习笔记]上传文件到EC2主机
- 《Spring技术内幕》学习笔记3——IoC容器载入Bean定义资源文件
- 第7周项目2 建立链队算法库
- HashMap和Hashtable的区别
- Android Activity生命周期以及Fragment生命周期的区别与分析
- Android测试环境搭建(win7)
- 第五周项目三 括号的匹配
- linux命令加杠不加杠,单杠与双杠