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

2019-12-10 19:08:02刘景俊

第二步、我们模拟打开通知栏

打开微信如下图:

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

我们查找包含有:领取红包 的文本内容的节点View,然后模拟点击,进入第三步:

第三步、我们点击领取红包

'如下图:

这里我们在查找包含有:拆红包 的文本内容的节点View,然后模拟点击

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

下面我们来看一下代码中的具体实现:

package krelve.demo.rob; 
import java.util.List; 
import android.accessibilityservice.AccessibilityService; 
import android.accessibilityservice.AccessibilityServiceInfo; 
import android.annotation.SuppressLint; 
import android.app.Notification; 
import android.app.PendingIntent; 
import android.app.PendingIntent.CanceledException; 
import android.util.Log; 
import android.view.accessibility.AccessibilityEvent; 
import android.view.accessibility.AccessibilityNodeInfo; 
public class RobMoney extends AccessibilityService { 
@Override 
public void onAccessibilityEvent(AccessibilityEvent event) { 
int eventType = event.getEventType(); 
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("[微信红包]")) { 
//模拟打开通知栏消息 
if (event.getParcelableData() != null 
&& 
event.getParcelableData() instanceof Notification) { 
Notification notification = (Notification) event.getParcelableData(); 
PendingIntent pendingIntent = notification.contentIntent; 
try { 
pendingIntent.send(); 
} catch (CanceledException e) { 
e.printStackTrace(); 
} 
} 
} 
} 
} 
break; 
//第二步:监听是否进入微信红包消息界面 
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: 
String className = event.getClassName().toString(); 
if (className.equals("com.tencent.mm.ui.LauncherUI")) { 
//开始抢红包 
getPacket(); 
} else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")) { 
//开始打开红包 
openPacket(); 
} 
break; 
} 
} 
/** 
* 查找到 
*/ 
@SuppressLint("NewApi") 
private void openPacket() { 
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); 
if (nodeInfo != null) { 
List<AccessibilityNodeInfo> list = nodeInfo 
.findAccessibilityNodeInfosByText("抢红包"); 
for (AccessibilityNodeInfo n : list) { 
n.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
} 
} 
} 
@SuppressLint("NewApi") 
private void getPacket() { 
AccessibilityNodeInfo rootNode = getRootInActiveWindow(); 
recycle(rootNode); 
} 
/** 
* 打印一个节点的结构 
* @param info 
*/ 
@SuppressLint("NewApi") 
public void recycle(AccessibilityNodeInfo info) { 
if (info.getChildCount() == 0) { 
if(info.getText() != null){ 
if("领取红包".equals(info.getText().toString())){ 
//这里有一个问题需要注意,就是需要找到一个可以点击的View 
Log.i("demo", "Click"+",isClick:"+info.isClickable()); 
info.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
AccessibilityNodeInfo parent = info.getParent(); 
while(parent != null){ 
Log.i("demo", "parent isClick:"+parent.isClickable()); 
if(parent.isClickable()){ 
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
break; 
} 
parent = parent.getParent(); 
} 
} 
} 
} else { 
for (int i = 0; i < info.getChildCount(); i++) { 
if(info.getChild(i)!=null){ 
recycle(info.getChild(i)); 
} 
} 
} 
} 
@Override 
public void onInterrupt() { 
} 
}