android 利用accessibilityservice 实现自动发红包功能 (让收红包的人手抽筋)(密码不能自动输入,可以开启指纹支付)
2017-10-18 16:04
1051 查看
简介
AccessibilityService是一个辅助类,可以监听我们手机的焦点,窗口变化,按钮点击,消息通知,文本内容等等。实现它的服务需要在手机设置里面->辅助功能(无障碍)在这里面找到你自己实现的服务;简单的说AccessibilityService就是一个后台监控服务,当你监控的内容发生改变时,就会调用后台服务的回调方法怎么使用 ?1.1创建自己的类 新建类 继承AccessibilityService,重写onAccessibilityEvent(AccessibilityEventaccessibilityEvent)方法,onServiceConnected()方法和onInterrupt()方法。1.2 声明服务
<service android:name="com.hqc.sendhongbao.MyAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" android:label="自动发红包"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config"/> </service>
1.3 配置参数
配置参数是指:配置用来接受指定类型的事件,指定反馈类型,监听指定package,检索窗口内容,获取事件类型的超时时间,服务描述等。其配置服务参数有两种方法:1.通过meta-data标签指定xml文件进行配置<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged|typeViewClicked" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" android:description="@string/accessibility_service_description" android:notificationTimeout="100" android:packageNames="com.tencent.mm"/>下面是对xml参数的介绍 copy。。。accessibilityEventTypes:表示该服务对界面中的哪些变化感兴趣,即哪些事件通知,比如窗口打开,滑动,焦点变化,长按等。具体的值可以在AccessibilityEvent类中查到,如typeAllMask表示接受所有的事件通知,accessibilityFeedbackType:表示反馈方式,比如是语音播放,还是震动canRetrieveWindowContent:表示该服务能否访问活动窗口中的内容。也就是如果你希望在服务中获取窗体内容,则需要设置其值为truedescription:对该无障碍功能的描述,在无障碍服务中显示,让用户了解该服务的功notificationTimeout:接受事件的时间间隔,通常将其设置为100即可packageNames:表示对该服务是用来监听哪个包的产生的事件,这里以微信的包名为例2. 服务类的代码 进行代码设置 , 忽略
1.4 处理事件回调信息
@Override public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) { AccessibilityNodeInfo source = accessibilityEvent.getSource(); if (source == null) {return;} int eventType = accessibilityEvent.getEventType(); switch (eventType) { case AccessibilityEvent.TYPE_VIEW_CLICKED: CharSequence des = source.getContentDescription(); // 这里监听微信的 +号。作为触发条件 if (des != null && des.equals("更多功能按钮,已展开")) { Log.d(TAG_RESLUT, "更多功能按钮,已展开"); //找到 当前窗口的 布局。。 AccessibilityNodeInfo window = getRootInActiveWindow(); //找到红包字符,模拟点击事件。注意这里的红包本身不带点击,能点击是他的 父布局 List<AccessibilityNodeInfo> hbInfos = window.findAccessibilityNodeInfosByText("红包"); ClickParent(hbInfos, "红包"); // 红包页面 打开了标识 hbUiopened = true; } break; case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: CharSequence desWindow = source.getContentDescription(); CharSequence className = source.getClassName(); // 这里有个问题 ,进入红包页面,时候有个进度条页面,使用dialog完成的。每次getRootInActiveWindow()获取到的 //是 进度条那个窗口的 布局。导致无法找到 对应的按钮,解决办法。模拟历史任务按键。再次返回到当前页面 能获取正确的window // 其他手机 可能没这个问题,因手机而不同 if (hbUiopened && desWindow != null && desWindow.equals("当前所在页面,发红包")) {//首次进入发红包页面。window为进度条页面 Log.d(TAG_RESLUT, "当前所在页面,发红包"); performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS); //定时器 Message message = handler.obtainMessage(); message.what = COME_IN_HB_UI; // 1秒后 再次模拟 历史任务键 返回到当前页面, 太快了。还在 进度条页面 message.getTarget().sendMessageDelayed(message, 1000); return; } if (isInHbUi) { //到红包页面了 AccessibilityNodeInfo window = getRootInActiveWindow(); if (window == null) { Log.d("window is null", "11"); return; } // t替换 moeny findNodeByTextAndSetNewValue(window, "0.00", String.valueOf(hbMoney)); if(!TextUtils.isEmpty(msg)){ // 替换 留言 findNodeByTextAndSetNewValue(window, "恭喜发财,大吉大利", msg); } List<AccessibilityNodeInfo> hbInfos = window.findAccessibilityNodeInfosByText("塞钱进红包"); ClickParent(hbInfos, "塞钱进红包"); isInHbUi = false; isInPayUi = true; return; } if (TextUtils.isEmpty(desWindow)) { return; } String windowStr = desWindow.toString(); // 检测 是否回到了 聊天页面 if (isInPayUi && windowStr != null && windowStr.contains("当前所在页面,") && windowStr.contains("聊天")) {//回到了 聊天页面 isInPayUi = false; realNum++; if(realNum== hbNum){//发送完毕 stopSelf(); return; } //再次模拟 点击红包事件 AccessibilityNodeInfo window = getRootInActiveWindow(); List<AccessibilityNodeInfo> hbInfos = window.findAccessibilityNodeInfosByText("红包"); ClickParent(hbInfos, "红包"); hbUiopened = true; } break; } }
// 替黄文字。。。 可以根据 findAccessibilityNodeInfosByText 找到对应的 nodeinfo,但有时候可能找不到, //可以做 window的遍历 public void findNodeByTextAndSetNewValue(AccessibilityNodeInfo info, String text, String newValue) { if (info.getChildCount() == 0 && text != null && text.equals(info.getText())) { if ("android.widget.EditText".equals(info.getClassName())) { Bundle arguments = new Bundle(); arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD); arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments); info.performAction(AccessibilityNodeInfo.ACTION_FOCUS); ClipData clip = ClipData.newPlainText("label", newValue); ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); clipboardManager.setPrimaryClip(clip); info.performAction(AccessibilityNodeInfo.ACTION_PASTE); } return; } else { for (int i = 0; i < info.getChildCount(); i++) { if (info.getChild(i) != null) { findNodeByTextAndSetNewValue(info.getChild(i), text, newValue); } } } }
// 模拟点击 事件,有可能你找到的 控件,不支持点击,只能向上 到父级 实现, fitle 控件名字,过滤掉其他的不需要的控件 // 比如你 根据 红包 找到 很多个可以点击的控件, 容易误操作 findAccessibilityNodeInfosByText方法 返回的是包含关系的 // 你 红包 关键字,返回的 拆红包, 领取红包 微信红包 等 private void ClickParent(List<AccessibilityNodeInfo> infos, String fitle) { if (infos == null) { return; } for (AccessibilityNodeInfo info : infos) { if (!info.isEnabled() || info.getText() == null || !info.getText().equals(fitle)) { continue; } if (info.isClickable()) { info.performAction(AccessibilityNodeInfo.ACTION_CLICK); } else { AccessibilityNodeInfo parent = info.getParent(); while (parent != null) { if (parent.isClickable()) { parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); break; } parent = parent.getParent(); } } } }
// hand 定时 private static final int COME_IN_HB_UI = 1; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case COME_IN_HB_UI: performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS); //加载完成 hbUiopened = false; isInHbUi = true; break; } } };注意,因为微信特殊处理,支付那个页面,不能模拟。故此只能手动输入,或者使用 指纹支付1.5 其他 是否安装该服务?注意 serviceName = 包名+类全名 或者 报名/.类名
String serviceName = getPackageName() + "/.MyAccessibilityService";
AccessibilityManager am = (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);boolean isInstall=false;List<AccessibilityServiceInfo> installedAccessibilityServiceList = am.getInstalledAccessibilityServiceList();for (AccessibilityServiceInfo info : installedAccessibilityServiceList) {Log.d("MainActivity", "all -->" + info.getId());if (serviceName.equals(info.getId())) {isInstall=true;break;}}是否启用该服务?
List<AccessibilityServiceInfo> serviceInfos = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);for (AccessibilityServiceInfo info : serviceInfos) {Log.d("MainActivity", "use -->" + info.getId());if (serviceName.equals(info.getId())) {isUse = true;break;}}跳转到设置页面 开启服务,只能跳转到页面,不能强制开启
/*** 跳转到系统设置页面开启辅助功能*/private void openAccessibility(){Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);startActivity(intent);}
相关文章推荐
- Android利用AccessibilityService实现抢红包,微信自动回复等功能思路
- Android——SharedPreferences实现登录界面的记住密码和自动登录功能
- Android实现利用手势完成屏幕密码锁功能
- Android——SharedPreferences实现登录界面的记住密码和自动登录功能
- Android 利用工具实现一键自动findViewById功能
- android利用service实现下载apk自动更新功能
- Flex中如何实现类似像QQ登录框中那种“记住密码”、“自动登录”功能,还有如何实现文本框中记录最后一次输入的值?
- 利用PHP安装windows自动运行的服务,PHP程序可以实现长时间、自动运行、定时更新功能,直接可以用在项目中的类源代码
- Android 利用AutoCompleteTextView实现模糊搜索功能,搜索结果自动提示,识别拼音首字母并转汉字提示
- Android实现动态自动匹配输入内容功能
- Android的支付密码输入框实现浅析
- Android开发(14)-- 多线程中实现利用自定义控件绘制小球并完成小球自动下落的功能
- Android通过SharedPreferences实现自动登录记住用户名和密码功能
- Android编程实现自定义输入法功能示例【输入密码时防止第三方窃取】
- android 中使用AutoCompleteTextView 可以实现自动提示功能
- Android开发之多线程中实现利用自定义控件绘制小球并完成小球自动下落功能实例
- Android辅助功能实现自动抢红包(附源码)
- 输入密码后自动登录功能的实现
- Shell脚本中调用expect,实现自动输入密码的功能
- Android-利用SharedPreferences实现记住密码和账号功能