android群聊红包原理,Android之微信抢红包实现原理分析
微信抢红包主要用到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之微信抢红包实现原理分析相关推荐
- Android微信抢红包插件原理和实现 适配微信6.6.1版本
Android微信抢红包插件原理和实现 适配微信6.6.1版本 一.前言 年关将至,小伙伴们又聊起了春节长假的旅行安排和各自家乡的年味习俗,不一而足.其中在各个微信群聊中抢红包也是为大家所津津乐道的. ...
- android黑科技系列——微信抢红包插件原理解析和开发实现
一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...
- android环信群聊显名称,Android环信群聊插入头像和昵称
最近在用环信开发项目中,发现环信的后台并不支持录入头像和昵称. 群聊的list列表中用户的头像是默认图,昵称是用户的id. 这显然很不友好,环信给出的方案如下: 方法一:从APP服务器获取昵称和头像 ...
- Android 挂逼 修炼之行---防自动抢红包外挂原理解析
一.前言 春节过年发个红包本来就是为了讨个喜庆,朋友亲戚之间的关系交流,但是现在随着技术变革,抢红包插件越来越多,导致现在不太愿意发红包了,特别是在一个多人群里,潜水的非常多,但是丢个红包瞬间就没了, ...
- python微信群聊机器人_Python + itchat 实现微信机器人聊天(支持自动回复指定群聊)...
Python + itchat 实现微信机器人聊天(支持自动回复指定群聊) 发布时间:2018-10-25 22:38, 浏览次数:600 , 标签: Python itchat <>Py ...
- 怎么从微信群聊中引流?如何从群聊进行引流?微信群怎么引流
在微信群当中,微信群裂变营销是很恐怖的的,但是,我们都知道微信群不像QQ群一样,没办法进行搜索,所以微信群引流就成为了许多人的难题,那么微信群聊怎么引流呢? 一.个人定位 做微信群引流之前,我们要先定 ...
- Android挂逼修炼之行---防自动抢红包外挂原理解析
一.前言 春节过年发个红包本来就是为了讨个喜庆,朋友亲戚之间的关系交流,但是现在随着技术变革,抢红包插件越来越多,导致现在不太愿意发红包了,特别是在一个多人群里,潜水的非常多,但是丢个红包瞬间就没了, ...
- 微信群聊小机器人的服务器,微信群里自动聊天的机器人是怎么弄的?有没有操作教程?...
原标题:微信群里自动聊天的机器人是怎么弄的?有没有操作教程? 很多人在做微信营销的时候都在群里放了个"机器人",这个机器人到底是什么来头,有这么神奇,这么智能吗? 其实这个机器人只 ...
- Android”挂逼”修炼之行—防自动抢红包外挂原理解析
一.前言 春节过年发个红包本来就是为了讨个喜庆,朋友亲戚之间的关系交流,但是现在随着技术变革,抢红包插件越来越多,导致现在不太愿意发红包了,特别是在一个多人群里,潜水的非常多,但是丢个红包瞬间就没了, ...
最新文章
- php追加编译imagick
- vue+element实现树状表格的增删改查;使用el-table树形数据与懒加载实现树状表格增删改查
- 95-180-045-源码-Watermark-递增时间戳分配器(AscendingTimestampExtractor)
- java 数组的应用(一维)
- http ,servlet
- VMware安装win7系统
- 12款免商用中文字体,有谁不爱!(附下载)
- android studio在夜神上打开_android studio 使用夜神模拟器 开发调试
- 解除宝塔面板强制绑定手机号教程
- 无线桥接:没有网口解决nas有线组网问题
- 英语单词之说文解字(7)
- Java加密解密代码小记
- 儿子懂得心痛他爸爸了
- python 图片抓取
- 电阻、电容和电感的选型及作用
- 数据库导入导出方法以及注意事项
- 二进制原码和补码的转换
- Mac电脑下 Idea 修改内存参数不起作用的解决方法
- MERCURY无线面板式AP-强电供电-WiFi密码-IP地址
- 小程序 - 实现【一键复制】功能