微信抢红包主要用到AccessibilityService,该服务需要用户手动到辅助功能里面授权,下面直接粘贴源码,先看Activity,主要是跳转到辅助功能界面,让用户开启辅助功能的服务:

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

View btn = findViewById(R.id.open_help_btn);

btn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(

android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);

startActivity(intent);

}

});

}

}

下面看服务的使用,需要配置相关参数,如:

android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged"

android:accessibilityFeedbackType="feedbackGeneric"

android:accessibilityFlags="flagDefault"

android:canRetrieveWindowContent="true"

android:description="@string/accessibility_description"

android:notificationTimeout="100"

android:packageNames="com.tencent.mm" />

再看服务的声明:

android:name="com.yongfei.hongbao.AccService"

android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >

android:name="android.accessibilityservice"

android:resource="@xml/service_config" />

最后看抢红包功能的实现:

public class AccService extends AccessibilityService {

private static final String NOTIFICATION_HONGBAO = "[微信红包]";

private static final String HONGBAO_MSG = "微信红包";

private static final String LAUNCHER_UI = "com.tencent.mm.ui.LauncherUI";

private static final String OPEN_MONEY_UI = "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI";

private static final String OPEN_ID = "com.tencent.mm:id/ba_";

private boolean mIsFromNotification = false;

// 标记在微信主界面时收到红包消息

private boolean mIsMsgWindow = true;

private WakeLock mWakeLock;

private KeyguardManager mKeyguardManager;

private KeyguardLock mKeyguardLock;

private boolean mIsOperationLock = false;

@Override

public void onAccessibilityEvent(AccessibilityEvent event) {

int eventType = event.getEventType();

if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {

List text = event.getText();

if (!text.isEmpty()) {

for (CharSequence item : text) {

String t = String.valueOf(item);

System.out.println("zyf通知内容:" + t);

if (t.contains(NOTIFICATION_HONGBAO)) {

mIsFromNotification = true;

mIsMsgWindow = true;

if (isKeyguardLocked()) {

wakeAndUnlock(true);

}

openNotification(event);

break;

}

}

}

} else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {

mIsMsgWindow = false;

// 只有从通知栏进入聊天界面的才点击红包消息/拆红包

// 因为拆完红包返回时也会引起窗口变化

if (mIsFromNotification) {

windowStateChanged(event);

return;

}

// 聊天界面手动点击红包消息时,自动拆包

if (OPEN_MONEY_UI.equals(event.getClassName())) {

// 拆红包界面,点击拆红包

openHongBao();

}

}

}

private void wakeAndUnlock(boolean unlock) {

if (unlock) {

PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);

mWakeLock = manager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP

| PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "money");

mWakeLock.acquire();

if (mKeyguardManager != null) {

mKeyguardLock = mKeyguardManager.newKeyguardLock("unLock");

mKeyguardLock.disableKeyguard();

mIsOperationLock = true;

}

} else {

if (mKeyguardLock != null) {

mKeyguardLock.reenableKeyguard();

mIsOperationLock = false;

}

if (mWakeLock != null) {

mWakeLock.release();

}

}

}

private boolean isKeyguardLocked() {

mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);

return mKeyguardManager.isKeyguardLocked();

}

/**

* 界面变化

*

* @param event

*/

private void windowStateChanged(AccessibilityEvent event) {

if (LAUNCHER_UI.equals(event.getClassName())) {

// 主界面或聊天界面,点击红包消息

clickHongBaoMsg();

} else if (OPEN_MONEY_UI.equals(event.getClassName())) {

// 拆红包界面,点击拆红包

openHongBao();

}

}

/**

* 拆红包

*/

private void openHongBao() {

AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();

if (nodeInfo == null) {

System.out.println("zyf openHongBao is null");

return;

}

// 抢别人发的红包

List openId = nodeInfo

.findAccessibilityNodeInfosByViewId(OPEN_ID);

if (openId != null && openId.size() > 0) {

openId.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);

if (mIsOperationLock) {

wakeAndUnlock(false);

}

}

// 抢没抢到红包都要把变量赋为false,以便后续继续拆从通知栏进来的红包消息

mIsFromNotification = false;

}

/**

* 点击红包消息

*/

private void clickHongBaoMsg() {

AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();

if (nodeInfo == null) {

System.out.println("zyf rootwindow is null");

return;

}

List list = nodeInfo

.findAccessibilityNodeInfosByText(HONGBAO_MSG);

if (list.size() >= 1) {

// 只拆最后一个红包

AccessibilityNodeInfo item = list.get(list.size() - 1);

AccessibilityNodeInfo parent = item.getParent();

parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);

}

}

/**

* 打开通知栏消息

*

* @param event

*/

private void openNotification(AccessibilityEvent event) {

if (event.getParcelableData() == null

|| !(event.getParcelableData() instanceof Notification)) {

return;

}

// 获取通知栏的意图并打开

Notification notification = (Notification) event.getParcelableData();

PendingIntent pendingIntent = notification.contentIntent;

try {

pendingIntent.send();

// 只有接收到通知并且窗口没有变化时才需要点击红包消息

// 因为此时是在微信主界面

if (mIsMsgWindow) {

clickHongBaoMsg();

}

} catch (CanceledException e) {

e.printStackTrace();

}

}

@Override

public void onInterrupt() {

System.out.println("zyf 服务中断了");

}

@Override

protected void onServiceConnected() {

super.onServiceConnected();

System.out.println("zyf 服务连接成功");

}

}

由于上面用到wakelock和解锁/锁屏功能,故需要在配置文件中添加相关权限:

另外,需要把apk加入到各种白名单,因为应用被杀后辅助功能会自动收回该应用的授权。

另外,手机静音时该服务是不可用的。

上面代码是基于微信6.3.23版本实现的,不同版本id可能会不同。

android群聊红包原理,Android之微信抢红包实现原理分析相关推荐

  1. Android微信抢红包插件原理和实现 适配微信6.6.1版本

    Android微信抢红包插件原理和实现 适配微信6.6.1版本 一.前言 年关将至,小伙伴们又聊起了春节长假的旅行安排和各自家乡的年味习俗,不一而足.其中在各个微信群聊中抢红包也是为大家所津津乐道的. ...

  2. android黑科技系列——微信抢红包插件原理解析和开发实现

    一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  3. android环信群聊显名称,Android环信群聊插入头像和昵称

    最近在用环信开发项目中,发现环信的后台并不支持录入头像和昵称. 群聊的list列表中用户的头像是默认图,昵称是用户的id. 这显然很不友好,环信给出的方案如下: 方法一:从APP服务器获取昵称和头像 ...

  4. Android 挂逼 修炼之行---防自动抢红包外挂原理解析

    一.前言 春节过年发个红包本来就是为了讨个喜庆,朋友亲戚之间的关系交流,但是现在随着技术变革,抢红包插件越来越多,导致现在不太愿意发红包了,特别是在一个多人群里,潜水的非常多,但是丢个红包瞬间就没了, ...

  5. python微信群聊机器人_Python + itchat 实现微信机器人聊天(支持自动回复指定群聊)...

    Python + itchat 实现微信机器人聊天(支持自动回复指定群聊) 发布时间:2018-10-25 22:38, 浏览次数:600 , 标签: Python itchat <>Py ...

  6. 怎么从微信群聊中引流?如何从群聊进行引流?微信群怎么引流

    在微信群当中,微信群裂变营销是很恐怖的的,但是,我们都知道微信群不像QQ群一样,没办法进行搜索,所以微信群引流就成为了许多人的难题,那么微信群聊怎么引流呢? 一.个人定位 做微信群引流之前,我们要先定 ...

  7. Android挂逼修炼之行---防自动抢红包外挂原理解析

    一.前言 春节过年发个红包本来就是为了讨个喜庆,朋友亲戚之间的关系交流,但是现在随着技术变革,抢红包插件越来越多,导致现在不太愿意发红包了,特别是在一个多人群里,潜水的非常多,但是丢个红包瞬间就没了, ...

  8. 微信群聊小机器人的服务器,微信群里自动聊天的机器人是怎么弄的?有没有操作教程?...

    原标题:微信群里自动聊天的机器人是怎么弄的?有没有操作教程? 很多人在做微信营销的时候都在群里放了个"机器人",这个机器人到底是什么来头,有这么神奇,这么智能吗? 其实这个机器人只 ...

  9. Android”挂逼”修炼之行—防自动抢红包外挂原理解析

    一.前言 春节过年发个红包本来就是为了讨个喜庆,朋友亲戚之间的关系交流,但是现在随着技术变革,抢红包插件越来越多,导致现在不太愿意发红包了,特别是在一个多人群里,潜水的非常多,但是丢个红包瞬间就没了, ...

最新文章

  1. php追加编译imagick
  2. vue+element实现树状表格的增删改查;使用el-table树形数据与懒加载实现树状表格增删改查
  3. 95-180-045-源码-Watermark-递增时间戳分配器(AscendingTimestampExtractor)
  4. java 数组的应用(一维)
  5. http ,servlet
  6. VMware安装win7系统
  7. 12款免商用中文字体,有谁不爱!(附下载)
  8. android studio在夜神上打开_android studio 使用夜神模拟器 开发调试
  9. 解除宝塔面板强制绑定手机号教程
  10. 无线桥接:没有网口解决nas有线组网问题
  11. 英语单词之说文解字(7)
  12. Java加密解密代码小记
  13. 儿子懂得心痛他爸爸了
  14. python 图片抓取
  15. 电阻、电容和电感的选型及作用
  16. 数据库导入导出方法以及注意事项
  17. 二进制原码和补码的转换
  18. Mac电脑下 Idea 修改内存参数不起作用的解决方法
  19. MERCURY无线面板式AP-强电供电-WiFi密码-IP地址
  20. 小程序 - 实现【一键复制】功能

热门文章

  1. 数据架构:数据中心 主备、双活
  2. 俄罗斯方块游戏算法分析
  3. 理解“卷积” Understanding Convolutions
  4. 计算机编程小学生有必要学吗,小学生有必要学少儿编程吗
  5. 《ssh权威指南》书评
  6. windows平台简单的FTP服务器,无需安装
  7. python: del函数
  8. 武学大陆-为啥要学IT绝世武功
  9. java获取服务器ip地址_java中获取当前服务器的Ip地址的方法
  10. 不看后悔!阿里内部技术参考图册算法篇!(附网盘链接)