Android辅助功能AccessibilityService与抢红包辅助

推荐阅读:Android中微信抢红包插件原理解析及开发思路

抢红包的原理都差不多,一般是用Android的辅助功能(AccessibilityService类)先监听通知栏事件或窗口变化事件来查找红包关键字然后去模拟点击或打开红包。

下面附上源码,程序已实现自动抢红包,锁屏黑屏状态自动解锁亮屏,Android4.X测试通过。函数具体功能请看详细注释。
注:在聊天界面收到红包不会自动打开,因为通知栏没有消息提示从而监听不了,此时只需手动点一下即可。其他未知情况请自行用LogCat调试,源码已经有相关的调试信息。软件仅供学习娱乐。

<pre style="margin-top: 0px; margin-bottom: 0px;"><span style="font-family: Arial, Helvetica, sans-serif; color: rgb(192, 192, 192);"></span><pre style="margin-top: 0px; margin-bottom: 0px;">import java.util.Calendar; import java.util.List; import android.accessibilityservice.AccessibilityService; import android.annotation.SuppressLint; import android.app.KeyguardManager; import android.app.KeyguardManager.KeyguardLock; import android.app.Notification; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; import android.content.Context; import android.media.MediaPlayer; import android.os.PowerManager; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Toast; public class Demo extends AccessibilityService { private boolean canGet = false;//能否点击红包 private boolean enableKeyguard = true;//默认有屏幕锁 //窗口状态 private static final int WINDOW_NONE = 0; private static final int WINDOW_LUCKYMONEY_RECEIVEUI = 1; private static final int WINDOW_LUCKYMONEY_DETAIL = 2; private static final int WINDOW_LAUNCHER = 3; private static final int WINDOW_OTHER = -1; //当前窗口 private int mCurrentWindow = WINDOW_NONE; //锁屏、解锁相关 private KeyguardManager km; private KeyguardLock kl; //唤醒屏幕相关 private PowerManager pm; private PowerManager.WakeLock wl = null; //播放提示声音 private MediaPlayer player; public void playSound(Context context) { Calendar cal = Calendar.getInstance(); int hour = cal.get(Calendar.HOUR_OF_DAY); //夜间不播放提示音 if(hour > 7 && hour < 22) { player.start(); } } //唤醒屏幕和解锁 private void wakeAndUnlock(boolean unLock) { if(unLock) { //若为黑屏状态则唤醒屏幕 if(!pm.isScreenOn()) { //获取电源管理器对象,ACQUIRE_CAUSES_WAKEUP这个参数能从黑屏唤醒屏幕 wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "bright"); //点亮屏幕 wl.acquire(); Log.i("demo", "亮屏"); } //若在锁屏界面则解锁直接跳过锁屏 if(km.inKeyguardRestrictedInputMode()) { //设置解锁标志,以判断抢完红包能否锁屏 enableKeyguard = false; //解锁 kl.disableKeyguard(); Log.i("demo", "解锁"); } } else { //如果之前解过锁则加锁以恢复原样 if(!enableKeyguard) { //锁屏 kl.reenableKeyguard(); Log.i("demo", "加锁"); } //若之前唤醒过屏幕则释放之使屏幕不保持常亮 if(wl != null) { wl.release(); wl = null; Log.i("demo", "关灯"); } } } //通过文本查找节点 public AccessibilityNodeInfo findNodeInfosByText(AccessibilityNodeInfo nodeInfo, String text) { List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText(text); if(list == null || list.isEmpty()) { return null; } return list.get(0); } //模拟点击事件 public void performClick(AccessibilityNodeInfo nodeInfo) { if(nodeInfo == null) { return; } if(nodeInfo.isClickable()) { nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); } else { performClick(nodeInfo.getParent()); } } //模拟返回事件 public void performBack(AccessibilityService service) { if(service == null) { return; } service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK); } //实现辅助功能 @Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventType = event.getEventType(); Log.i("demo", Integer.toString(eventType)); switch (eventType) { //第一步:监听通知栏消息 case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: List<CharSequence> texts = event.getText(); if (!texts.isEmpty()) { for (CharSequence text : texts) { String content = text.toString(); Log.i("demo", "text:"+content); //收到红包提醒 if (content.contains("[微信红包]")||content.contains("[QQ红包]")) { //模拟打开通知栏消息 if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) { //播放提示音 playSound(this); //若是微信红包则解锁并自动打开,若是qq红包则只提示并跳转到有红包的聊天界面,暂未实现qq红包自动领取功能 if(content.contains("[微信红包]")) wakeAndUnlock(true); Log.i("demo", "canGet=true"); canGet = true; try { Notification notification = (Notification) event.getParcelableData(); PendingIntent pendingIntent = notification.contentIntent; pendingIntent.send(); } catch (CanceledException e) { e.printStackTrace(); } } break; } } } break; //第二步:监听是否进入微信红包消息界面 case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: String className = event.getClassName().toString(); if (className.equals("com.tencent.mm.ui.LauncherUI")) { mCurrentWindow = WINDOW_LAUNCHER; //开始抢红包 Log.i("demo", "准备抢红包..."); getPacket(); } else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")) { mCurrentWindow = WINDOW_LUCKYMONEY_RECEIVEUI; //开始打开红包 Log.i("demo", "打开红包"); openPacket(); wakeAndUnlock(false); } else if(className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI")) { mCurrentWindow = WINDOW_LUCKYMONEY_DETAIL; //返回以方便下次收红包 Log.i("demo", "返回"); performBack(this); } else { mCurrentWindow = WINDOW_OTHER; } break; case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: if(mCurrentWindow != WINDOW_LAUNCHER) { //不在聊天界面或聊天列表,不处理 return; } if(canGet) { getPacket(); } break; } } //找到红包并点击 @SuppressLint("NewApi") private void getPacket() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo == null) { return; } // 找到领取红包的点击事件 List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("领取红包"); if(list != null ) { if(list.isEmpty()) { Log.i("demp", "领取列表为空"); // 从消息列表查找红包 AccessibilityNodeInfo node = findNodeInfosByText(nodeInfo, "[微信红包]"); if(node != null) { canGet = true; performClick(node); } } else { if(canGet) { //最新的红包领起 AccessibilityNodeInfo node = list.get(list.size() - 1); performClick(node); Log.i("demo", "canGet=false"); canGet = false; } } } } //打开红包 @SuppressLint("NewApi") private void openPacket() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if(nodeInfo == null) { return; } Log.i("demo", "查找打开按钮..."); AccessibilityNodeInfo targetNode = null; //如果红包已经被抢完则直接返回 targetNode = findNodeInfosByText(nodeInfo, "看看大家的手气"); if(targetNode != null) { performBack(this); return; } //通过组件名查找开红包按钮,还可通过组件id直接查找但需要知道id且id容易随版本更新而变化,旧版微信还可直接搜“開”字找到按钮 if(targetNode == null) { Log.i("demo", "打开按钮中..."); for (int i = 0; i < nodeInfo.getChildCount(); i++) { AccessibilityNodeInfo node = nodeInfo.getChild(i); if("android.widget.Button".equals(node.getClassName())) { targetNode = node; break; } } } //若查找到打开按钮则模拟点击 if(targetNode != null) { final AccessibilityNodeInfo n = targetNode; performClick(n); } } @Override public void onInterrupt() { Toast.makeText(this, "抢红包服务被中断啦~", Toast.LENGTH_LONG).show(); } @Override protected void onServiceConnected() { super.onServiceConnected(); Log.i("demo", "开启"); //获取电源管理器对象 pm=(PowerManager)getSystemService(Context.POWER_SERVICE); //得到键盘锁管理器对象 km= (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE); //初始化一个键盘锁管理器对象 kl = km.newKeyguardLock("unLock"); //初始化音频 player = MediaPlayer.create(this, R.raw.songtip_m); Toast.makeText(this, "_已开启抢红包服务_", Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { super.onDestroy(); Log.i("demo", "关闭"); wakeAndUnlock(false); Toast.makeText(this, "_已关闭抢红包服务_", Toast.LENGTH_LONG).show(); } }

AndroidManifest.xml中声明相关服务和权限

<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <pre name="code" class="html"><service android:name="com.example.test.Demo" android:enabled="true" android:exported="true" android:label="@string/app_name" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" > <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@layout/accessibility_config"/></service></application>

accessibility_config.xml服务配置内容如下

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged|typeWindowContentChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" android:description="@string/desc" android:notificationTimeout="100" android:packageNames= "com.tencent.mm,com.tencent.mobileqq" />

其中description为辅助功能的描述内容,packageNames为监听的程序包名,此处只监听微信和QQ的accessibilityEventTypes

以上所述是针对Android辅助功能AccessibilityService与抢红包辅助的相关知识,希望对大家有所帮助。

时间: 2024-09-20 05:34:15

Android辅助功能AccessibilityService与抢红包辅助的相关文章

Android辅助功能AccessibilityService与抢红包辅助_Android

推荐阅读:Android中微信抢红包插件原理解析及开发思路 抢红包的原理都差不多,一般是用Android的辅助功能(AccessibilityService类)先监听通知栏事件或窗口变化事件来查找红包关键字然后去模拟点击或打开红包. 下面附上源码,程序已实现自动抢红包,锁屏黑屏状态自动解锁亮屏,Android4.X测试通过.函数具体功能请看详细注释. 注:在聊天界面收到红包不会自动打开,因为通知栏没有消息提示从而监听不了,此时只需手动点一下即可.其他未知情况请自行用LogCat调试,源码已经有相

Android实现微信自动抢红包的程序_Android

 简单实现了微信自动抢红包的服务,原理就是根据关键字找到相应的View, 然后自动点击.主要是用到AccessibilityService这个辅助服务,基本可以满足自动抢红包的功能,但是有些逻辑需要优化,比如,拆完一个红包后,必须手动点击返回键,才能进行下一次自动抢红包. AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="

Android实现微信自动抢红包的程序

简单实现了微信自动抢红包的服务,原理就是根据关键字找到相应的View, 然后自动点击.主要是用到AccessibilityService这个辅助服务,基本可以满足自动抢红包的功能,但是有些逻辑需要优化,比如,拆完一个红包后,必须手动点击返回键,才能进行下一次自动抢红包. AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="h

Android AccessibilityService实现微信抢红包插件_Android

在你的手机更多设置或者高级设置中,我们会发现有个无障碍的功能,很多人不知道这个功能具体是干嘛的,其实这个功能是为了增强用户界面以帮助残障人士,或者可能暂时无法与设备充分交互的人们 它的具体实现是通过AccessibilityService服务运行在后台中,通过AccessibilityEvent接收指定事件的回调.这样的事件表示用户在界面中的一些状态转换,例如:焦点改变了,一个按钮被点击,等等.这样的服务可以选择请求活动窗口的内容的能力.简单的说AccessibilityService就是一个后

Android AccessibilityService实现微信抢红包插件

在你的手机更多设置或者高级设置中,我们会发现有个无障碍的功能,很多人不知道这个功能具体是干嘛的,其实这个功能是为了增强用户界面以帮助残障人士,或者可能暂时无法与设备充分交互的人们 它的具体实现是通过AccessibilityService服务运行在后台中,通过AccessibilityEvent接收指定事件的回调.这样的事件表示用户在界面中的一些状态转换,例如:焦点改变了,一个按钮被点击,等等.这样的服务可以选择请求活动窗口的内容的能力.简单的说AccessibilityService就是一个后

Android中微信抢红包插件原理解析及开发思路_Android

一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导致了.或许是网络的原因,而且这个也是最大的原因.但是其他的不可忽略的因素也是要考虑到进去的,比如在手机充电锁屏的时候,我们并不知道有人已经开始发红包了,那么这时候也是让我们丧失了一大批红包的原因.那么关于网络的问题,我们开发者可能用相关技术无法解决(当然在Google和Facebook看来的话,他们

Android中微信抢红包插件原理解析及开发思路

一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导致了.或许是网络的原因,而且这个也是最大的原因.但是其他的不可忽略的因素也是要考虑到进去的,比如在手机充电锁屏的时候,我们并不知道有人已经开始发红包了,那么这时候也是让我们丧失了一大批红包的原因.那么关于网络的问题,我们开发者可能用相关技术无法解决(当然在Google和Facebook看来的话,他们

Android Accessibility 辅助功能简单介绍_Android

Android Accessibility 辅助功能 Accessibility: 许多Android使用者因为各种情况导致他们要以不同的方式与手机交互. 这包括了有些用户由于视力上,身体上,年龄上的问题致使他们不能看完整的屏幕或者使用触屏,也包括了无法很好接收到语音信息和提示的听力能力比较弱的用户. Android提供了Accessibility功能和服务帮助这些用户更加简单地操作设备,包括文字转语音(这个不支持中文),触觉反馈,手势操作,轨迹球和手柄操作. 开发者可以利用这些服务使得程序更好

Android微信自动抢红包插件优化和实现_Android

又是兴趣系列 网上有很多自动强红包的例子和代码,笔者也是做了一些优化. 先说说自己的两个个优势 1.可以在聊天界面自动强不依赖于通知栏推送 2.可以在屏幕熄灭的时候的时候点亮屏幕自动抢(目前只测过flyme) 先上图: 代码传送门: https://github.com/AndroidMsky/WXhongbao 欢迎点星星~ 原理: 通过AccessibilityService监听到状态栏通知,进行模拟点击,获取屏幕中view节点为领取红包的list并且点击最后一个. 如果不通过状态栏通知,通