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

推荐阅读: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与抢红包辅助的相关知识,希望对大家有所帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索AccessibilityService
抢红包辅助
accessibility 抢红包、accessibilityservice、倩女幽魂抢红包辅助、征途2抢红包辅助、魔法王座抢红包辅助,以便于您获取更多的相关知识。

时间: 2024-09-20 00:49:29

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

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

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

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

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

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 中的注解详细介绍_Android

注解是我们经常接触的技术,Java有注解,Android也有注解,本文将试图介绍Android中的注解,以及ButterKnife和Otto这些基于注解的库的一些工作原理. 归纳而言,Android中的注解大概有以下好处 提高我们的开发效率 更早的发现程序的问题或者错误 更好的增加代码的描述能力 更加利于我们的一些规范约束 提供解决问题的更优解 准备工作 默认情况下,Android中的注解包并没有包括在framework中,它独立成一个单独的包,通常我们需要引入这个包. dependencies

Android 中的注解深入探究_Android

本文系GDG Android Meetup分享内容总结文章 注解是我们经常接触的技术,Java有注解,Android也有注解,本文将试图介绍Android中的注解,以及ButterKnife和Otto这些基于注解的库的一些工作原理. 归纳而言,Android中的注解大概有以下好处 提高我们的开发效率 更早的发现程序的问题或者错误 更好的增加代码的描述能力 更加利于我们的一些规范约束 提供解决问题的更优解 准备工作 默认情况下,Android中的注解包并没有包括在framework中,它独立成一个

Android实现离线缓存的方法_Android

 离线缓存就是在网络畅通的情况下将从服务器收到的数据保存到本地,当网络断开之后直接读取本地文件中的数据.如Json 数据缓存到本地,在断网的状态下启动APP时读取本地缓存数据显示在界面上,常用的APP(网易新闻.知乎等等)都是支持离线缓存的,这样带来了更好的用户体验. 如果能够在调用网络接口后自动缓存返回的Json数据,下次在断网状态下调用这个接口获取到缓存的Json数据的话,那该多好呢?Volley做到了这一点. 因此,今天这篇文章介绍的就是使用Volley自带的数据缓存,配合Universa

Android实现屏幕旋转方法总结_Android

本文实例总结了Android实现屏幕旋转方法.分享给大家供大家参考.具体如下: 在介绍之前,我们需要先了解默认情况下android屏幕旋转的机制: 默认情况下,当用户手机的重力感应器打开后,旋转屏幕方向,会导致当前activity发生onDestroy-> onCreate,这样会重新构造当前activity和界面布局,如果在Camera界面,则表现为卡顿或者黑屏一段时间.如果是在横竖屏UI设计方面,那么想很好地支持屏幕旋转,则建议在res中建立layout-land和layout-port两个

Android 权限(permission)整理_Android

在Android的设计中,资源的访问或者网络连接,要得到这些服务都需要声明其访问权限,否则将无法正常工作.在Android中这样的权限有很多种,这里将各类访问权限一一罗列出来,供大家使用时参考之用.  1.android.permission.WRITE_USER_DICTIONARY 允许应用程序向用户词典中写入新词  2.android.permission.WRITE_SYNC_SETTINGS 写入Google在线同步设置  3.android.permission.WRITE_SOCI