热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

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

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

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

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

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

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 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 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 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 

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

 
 
 
    

accessibility_config.xml服务配置内容如下

 

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

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


推荐阅读
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 【Windows】实现微信双开或多开的方法及步骤详解
    本文介绍了在Windows系统下实现微信双开或多开的方法,通过安装微信电脑版、复制微信程序启动路径、修改文本文件为bat文件等步骤,实现同时登录两个或多个微信的效果。相比于使用虚拟机的方法,本方法更简单易行,适用于任何电脑,并且不会消耗过多系统资源。详细步骤和原理解释请参考本文内容。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
author-avatar
兴添刚
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有