原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0919/648.html
实现道理
通过行使AccessibilityService辅助服无,监测屏幕内容,如监听状况栏的信息,屏幕跳转等,App开发培训以此来实现自动拆红包的功效。对于AccessibilityService辅助服无,可以自行百度打听更多。
代码底子:
1.开始申明一个RedPacketService秉承自AccessibilityService,该服无类有两个方法必需重写,如下:
/**
* email:809362109@qq.com
*
* 抢红包服无类
*/
public class RedPacketService extends AccessibilityService {
/**
* 必需重写的方法:此方法用了接受体系发来的event。在你注册的event产生是被挪用。在全部性命周期会被挪用屡次。
*/
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
/**
* 必需重写的方法:体系要中缀此service回笼的相应时会挪用。在全部性命周期会被挪用屡次。
*/
@Override
public void onInterrupt() {
Toast.makeText(this, "我快被闭幕了啊-----", Toast.LENGTH_SHORT).show();
}
/**
* 服无已持续
*/
@Override
protected void onServiceConnected() {
Toast.makeText(this, "常州网站开发培训抢红包服无开启", Toast.LENGTH_SHORT).show();
super.onServiceConnected();
}
/**
* 服无已断开
*/
@Override
public boolean onUnbind(Intent intent) {
Toast.makeText(this, "抢红包服无已被关闭", Toast.LENGTH_SHORT).show();
return super.onUnbind(intent);
}
}
2.对我们的RedPacketService进行少许配置,这里配置方法可以选定代码动静配置(onServiceConnected里配置),也能够干脆在res/xml下新建.xml文件,没有xml文件夹就新建。这里我们将文件定名为redpacket_service_config.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault"
android:canRetrieveWindowContent="true"
android:description="@string/desc"
android:notificationTimeout="100"
android:packageNames="com.tencent.毫米" />
accessibilityEventTypes:
相应哪一品种型的事件,typeAllMask即是相应所有范例的事件了,另外另有单击、长按、滑动等。
accessibilityFeedbackType:
用甚么方法反应给用户,有语音播出和振动。可以配置少许TTS引擎,让它实现发音。
packageNames:
指定相应哪一个运用的事件。这里我们是写抢红包助手,就写微信的包名:com.tencent.毫米,如许便监听微信产生的事件了。
notificationTimeout:
相应时间
description:
辅助服无的形貌信息。
3.service是四大组件之一,需求在AndroidManifest进行配置,留意这里略微有些差别:
<!--抢红包服无-->
<service
android:name=".RedPacketService"
android:enabled="true"
android:exported="true"
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="@xml/redpacket_service_config"></meta-data>
</service>
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" 权限请求
android:resource="@xml/redpacket_service_config" 引用适才的配置文件焦点代码:我们的红包助手,焦点思绪分为三步走:
监听关照栏微信消息,要是弹出[微信红包]字样,模拟手辅导击状况栏跳转到微信谈天界面→在微信谈天界面查找红包,要是找到则模拟手辅导击翻开,弹出翻开红包界面→模拟手辅导击红包“開”
1.监听软件技术企业培训关照栏消息,查看是否有[微信红包]字样,代码如下:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventType = event.getEventType();
switch (eventType) {
//关照栏来信息,校验是否含有微信红包字样,是的话跳转
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
List<CharSequence> texts = event.getText();
for (CharSequence text : texts) {
String content = text.toString();
if (!TextUtils.isEmpty(content)) {
//校验是否含有[微信红包]字样
if (content.contains("[微信红包]")) {
//要是有则翻开微信红包页面
openWeChatPage(event);
}
}
}
break;
}
}
/**
* 开启红包所在的谈天页面
*/
private void openWeChatPage(AccessibilityEvent event) {
//A instanceof B 用来校验内存中现实工具A是不是B范例,常用于强迫转换前的校验
if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
Notification notification = (Notification) event.getParcelableData();
//翻开对应的谈天界面
PendingIntent pendingIntent = notification.contentIntent;
try {
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
}
2.校验目前是否在微信谈天页面,是的话遍历目前页面各个控件,找到含有微信红包或者领取红包的textview控件,而后逐层找到他的可点击父结构(图中绿色片面),模拟点击跳转到含有“開”的红包界面,代码如下:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventType = event.getEventType();
switch (eventType) {
//窗口产生改变时会挪用该事件
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
String className = event.getClassName().toString();
//校验是否是微信谈天界面
if ("com.tencent.毫米.ui.LauncherUI".equals(className)) {
//获取目前谈天页面的根结构
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
//开始找红包
findRedPacket(rootNode);
}
}
}
/**
* 遍历查找红包
*/
private void findRedPacket(AccessibilityNodeInfo rootNode) {
if (rootNode != null) {
//从非常后一行开始找起
for (int i = rootNode.getChildCount() - 1; i >= 0; i--) {
AccessibilityNodeInfo node = rootNode.getChild(i);
//要是node为空则跳过该节点
if (node == null) {
continue;
}
CharSequence text = node.getText();
if (text != null && text.toString().equals("领取红包")) {
AccessibilityNodeInfo parent = node.getParent();
//while轮回,遍历"领取常州软件技术培训红包"的各个父结构,直至找到可点击的为止
while (parent != null) {
if (parent.isClickable()) {
//模拟点击
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
//isOpenRP用于校验该红包是否点击过
isOpenRP = true;
break;
}
parent = parent.getParent();
}
}
//校验是否曾经翻开过那个非常新的红包了,是的话就跳出for轮回,不是的话继续遍历
if (isOpenRP) {
break;
} else {
findRedPacket(node);
}
}
}
}
3.点击红包后,在模拟手辅导击“開”以此开启红包,跳转到红包细目界面,方法与步骤二相似:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventType = event.getEventType();
switch (eventType) {
//窗口产生改变时会挪用该事件
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
String className = event.getClassName().toString();
//校验是否是显示‘开’的那个红包界面
if ("com.tencent.毫米.plugin.luckymoney.ui.LuckyMoneyReceiveUI".equals(className)) {
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
//开始抢红包
openRedPacket(rootNode);
}
break;
}
}
/**
* 开始翻开红包
*/
private void openRedPacket(AccessibilityNodeInfo rootNode) {
for (int i = 0; i < rootNode.getChildCount(); i++) {
AccessibilityNodeInfo node = rootNode.getChild(i);
if ("android.widget.Button".equals(node.getClassName())) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
openRedPacket(node);
}
}
连结以上三步,下面是完备代码,注释曾经写的很清楚,干脆看代码:
package com.cxk.redpacket;
import android.accessibilityservice.AccessibilityService;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;
import java.util.List;
/**
* 抢红包Service,秉承AccessibilityService
*/
public class RedPacketService extends AccessibilityService {
/**
* 微信几个页面的包名+地点。常州平台运营用于校验在哪一个页面 LAUCHER-微信谈天界面,LUCKEY_MONEY_RECEIVER-点击红包弹出的界面
*/
private String LAUCHER = "com.tencent.毫米.ui.LauncherUI";
private String LUCKEY_MONEY_DETAIL = "com.tencent.毫米.plugin.luckymoney.ui.LuckyMoneyDetailUI";
private String LUCKEY_MONEY_RECEIVER = "com.tencent.毫米.plugin.luckymoney.ui.LuckyMoneyReceiveUI";
/**
* 用于校验是否点击过红包了
*/
private boolean isOpenRP;
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventType = event.getEventType();
switch (eventType) {
//关照栏来信息,校验是否含有微信红包字样,是的话跳转
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
List<CharSequence> texts = event.getText();
for (CharSequence text : texts) {
String content = text.toString();
if (!TextUtils.isEmpty(content)) {
//校验是否含有[微信红包]字样
if (content.contains("[微信红包]")) {
//要是有则翻开微信红包页面
openWeChatPage(event);
isOpenRP=false;
}
}
}
break;
//界面跳转的监听
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
String className = event.getClassName().toString();
//校验是否是微信谈天界面
if (LAUCHER.equals(className)) {
//获取目前谈天页面的根结构
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
//开始找红包
findRedPacket(rootNode);
}
//校验是否是显示‘开’的那个红包界面
if (LUCKEY_MONEY_RECEIVER.equals(className)) {
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
//开始抢红包
openRedPacket(rootNode);
}
//校验是否是红包领取后的细目界面
if(LUCKEY_MONEY_DETAIL.equals(className)){
//回笼桌面
back2Home();
}
break;
}
}
/**
* 开始翻开红包
*/
private void openRedPacket(AccessibilityNodeInfo rootNode) {
for (int i = 0; i < rootNode.getChildCount(); i++) {
AccessibilityNodeInfo node = rootNode.getChild(i);
if ("android.widget.Button".equals(node.getClassName())) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
openRedPacket(node);
}
}
/**
* 遍历查找红包
*/
private void findRedPacket(AccessibilityNodeInfo rootNode) {
if (rootNode != null) {
//从非常后一行开始找起
for (int i = rootNode.getChildCount() - 1; i >= 0; i--) {
AccessibilityNodeInfo node = rootNode.getChild(i);
//要是node为空则跳过该节点
if (node == null) {
continue;
}
CharSequence text = node.getText();
if (text != null && text.toString().equals("领取红包")) {
AccessibilityNodeInfo parent = node.getParent();
//while轮回,遍历"领取红包"的各个父结构,直至找到可点击的为止
while (parent != null) {
if (parent.isClickable()) {
//模拟点击
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
//isOpenRP用于校验该红包是否点击过
isOpenRP = true;
break;
}
parent = parent.getParent();
}
}
//校验是否曾经翻开过那个非常新的红包了,是的话就跳出for轮回,不是的话继续遍历
if (isOpenRP) {
break;
} else {
findRedPacket(node);
}
}
}
}
/**
* 开启红包所在的谈天页面
*/
private void openWeChatPage(AccessibilityEvent event) {
//A instanceof B 用来校验内存中现实工具A是不是B范例,常用于强迫转换前的校验
if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
Notification notification = (Notification) event.getParcelableData();
//翻开对应的谈天界面
PendingIntent pendingIntent = notification.contentIntent;
try {
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
}
/**
* 服无持续
*/
@Override
protected void onServiceConnected() {
Toast.makeText(this, "抢红包服无开启", Toast.LENGTH_SHORT).show();
super.onServiceConnected();
}
/**
* 必需重写的方法:体系要中缀此service回笼的相应时会挪用。在全部性命周期会被挪用屡次。
*/
@Override
public void onInterrupt() {
Toast.makeText(this, "我快被闭幕了啊-----", Toast.LENGTH_SHORT).show();
}
/**
* 服无断开
*/
@Override
public boolean onUnbind(Intent intent) {
Toast.makeText(this, "抢红包服无已被关闭", Toast.LENGTH_SHORT).show();
return super.onUnbind(intent);
}
/**
* 回笼桌面
*/
private void back2Home() {
Intent home=new Intent(Intent.ACTION_MAIN);
home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
home.addCategory(Intent.CATEGORY_HOME);
startActivity(home);
}
}
应用方法:
配置-辅助功效-无停滞-点击RedPacket开启即可
上篇:上一篇:Android 获取Device Id
下篇:下一篇:Android6.0run时权限请求计划