[置顶] 300行代码实现 微信或QQ 抢红包功能
2016-12-28 11:31
951 查看
每次看到别人发红包,但是没有抢到,这就很尴尬了。于是想着做一个红包插件,嘿嘿,再也不怕我反应迟钝了。
首先,想到做这个功能时,我联想到的是这个是不是lua写出来的脚本呢?但是条件不成立,因为可以不需要ROOT的。那么问题就来了,这玩意怎么实现?网上查了查,这下子明白了,Android平台为了给一些使用手机不是很方便的人提供了一个解决方案,被叫做AccessibilityService。这是一个辅助类,用于监听手机的焦点,窗口变化,按钮点击等等。
接下来,分析了源码上的绿色字体,大致意思如下:
继续往下看代码,Callbacks里有onAccessibilityEvent、onInterrupt和onServiceConnected是很重要的。
关于onAccessibilityEvent,源码的解释:
意思大致是我们需要继承AccessibilityService,然后实现onAccessibilityEvent方法。
关于onInterrupt,源码的解释:
这个是用功能中断时回调。
关于onServiceConnected,源码的解释:
系统成功绑定后回调,前面提到的代码配置也是在这个方法内。
好了,源码看到这里。我们需要的几个方法都了解了,接下来直接来看代码。首先创建工程,然后创建一个RBAccessibilityService继承自AccessibilityService。实现onAccessibilityEvent、onInterrupt和onServiceConnected方法。然后配置manifest
我们需要注意的是meta-data里的resource,这里需要在res创建一个xml文件夹,写入如下代码:
packageNames里的是需要监听的包名,需逗号隔开。配置完成,继续实现具体代码,完善RBAccessibilityService的onAccessibilityEvent:
看明白了么?这个方法内TYPE_NOTIFICATION_STATE_CHANGED状态就是监听微信或QQ发送红包过来时出现的notification,然后通过这个notification进入出现该红包的聊天页面。这个时候
窗口状态也变换了,又运行到了TYPE_WINDOW_STATE_CHANGED这个状态,这时我们的微信或QQ应该还是在聊天页面,接下来去实现点击或打开功能。需要注意的是,微信打开红包需要两次点击,先是领取,然后打开,但是QQ只需要一次点击,微信红包较简单,只有一种类型,QQ红包类型有两种。所以我们应该在窗口变化之前监听是QQ还是微信发送过来的红包,然后根据不同的值去做不同的动作。
这里面有个巧妙的点,就是开始时我始终找不到红包RelativeLayout的ID,那可怎么办呢,我继续往外层查找,红包外层还是一层RelativeLayout,但是content-desc中的值是 “xxxx,点击查看详情”。
明白了吗?没错,我通过文本查找遇到有文字包含有这个时再去实现点击nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
那么口令红包又是如何实现的呢?同理,也是需要通过文本查找文字
但是这里直接查找”口令红包”就可以了,查找到后实现点击,QQ会自动给我们出现一个按钮在输入框上方
继续查找文本并点击”点击输入口令”,这时候,输入框就有口令了,那么查找到发送的文本再实现一次点击,红包就领取成功了。
微信的红包和QQ 不一样的地方在于需要先点开红包出现一个红包页面,再点击红包才会打开红包。点开红包查找文本”领取红包”并实现点击,这时页面进入”com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI”
这时候显然通过文本查找是不行的了,因为这里只是一个Button,并没有文字,所以说需要另辟蹊径,因为当前页面仅有这一个Button,所以我们可以通过控件具体名字查找控件。
再实现一个点击事件。perfect,微信红包领取成功。
一个抢红包功能就这么愉快的搞定了!!快去试试吧!!你的点赞是对我最好的支持!!谢谢!!
最后附上CSDN下载链接和github的链接
http://download.csdn.net/detail/a876980961/9723236
https://github.com/a876980961/pop_hongbao_assistant
首先,想到做这个功能时,我联想到的是这个是不是lua写出来的脚本呢?但是条件不成立,因为可以不需要ROOT的。那么问题就来了,这玩意怎么实现?网上查了查,这下子明白了,Android平台为了给一些使用手机不是很方便的人提供了一个解决方案,被叫做AccessibilityService。这是一个辅助类,用于监听手机的焦点,窗口变化,按钮点击等等。
接下来,分析了源码上的绿色字体,大致意思如下:
无障碍服务的开发需要扩展这个类并实现其抽象方法。 生命周期 由系统和遵循已建立的服务生命周期 当用户在设备设置中或在设备设置期间关闭时,无障碍服务将停止 声明 必须完成2件事: 1.指定处理”android.accessibilityservice.AccessibilityService ” 2.请求android.Manifest.permission#BIND_ACCESSIBILITY_SERVICE权限使有且仅有系统可以绑定。 两种配置方法: 1.在manifest中设置; 2.在代码类中动态设置。 辅助功能可以配置为特定类型的辅助功能事件,仅监听特定的包,在给定的时间内做指定的事。
继续往下看代码,Callbacks里有onAccessibilityEvent、onInterrupt和onServiceConnected是很重要的。
关于onAccessibilityEvent,源码的解释:
The new event. This event is owned by the caller and cannot be used after this method returns. Services wishing to use the event after this method returns should make a copy.
意思大致是我们需要继承AccessibilityService,然后实现onAccessibilityEvent方法。
关于onInterrupt,源码的解释:
Callback for interrupting the accessibility feedback.
这个是用功能中断时回调。
关于onServiceConnected,源码的解释:
This method is a part of the {@link AccessibilityService} lifecycle and is called after the system has successfully bound to the service. If is convenient to use this method for setting the {@link AccessibilityServiceInfo}.
系统成功绑定后回调,前面提到的代码配置也是在这个方法内。
好了,源码看到这里。我们需要的几个方法都了解了,接下来直接来看代码。首先创建工程,然后创建一个RBAccessibilityService继承自AccessibilityService。实现onAccessibilityEvent、onInterrupt和onServiceConnected方法。然后配置manifest
<service android:name=".service.RBAccessibilityService" android:exported="true" android:enabled="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/accessibilityservice_set"> </meta-data> </service>
我们需要注意的是meta-data里的resource,这里需要在res创建一个xml文件夹,写入如下代码:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeAllMask" android:accessibilityFeedbackType="feedbackSpoken" android:accessibilityFlags="flagDefault" android:canRequestTouchExplorationMode="true" android:canRetrieveWindowContent="true" android:notificationTimeout="50" android:description="@string/accessibility_description" android:packageNames="com.tencent.mobileqq,com.tencent.mm"/>
packageNames里的是需要监听的包名,需逗号隔开。配置完成,继续实现具体代码,完善RBAccessibilityService的onAccessibilityEvent:
@Override public void onAccessibilityEvent(AccessibilityEvent event) { String className = event.getClassName().toString(); switch (event.getEventType()) { //通知栏 case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: List<CharSequence> texts = event.getText(); if (!texts.isEmpty()) { for (CharSequence text : texts) { String content = text.toString(); /** * 微信的notification */ if (content.contains(WECHAT_RB_TEXT)) { //赋值给判断值 QQ_OR_WECHAT = THISWECHAT; RBnotification(event); } /** * QQ的notification */ if (content.contains(QQ_RB_TXT)) { //赋值给判断值 QQ_OR_WECHAT = THISQQ; RBnotification(event); } } } break; case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: //判断是QQ或者微信发送来的红包 if (QQ_OR_WECHAT == THISQQ) { openQQHongBao(event); } else { openWeChatHongBao(event); } break; case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: break; default: break; } }
看明白了么?这个方法内TYPE_NOTIFICATION_STATE_CHANGED状态就是监听微信或QQ发送红包过来时出现的notification,然后通过这个notification进入出现该红包的聊天页面。这个时候
窗口状态也变换了,又运行到了TYPE_WINDOW_STATE_CHANGED这个状态,这时我们的微信或QQ应该还是在聊天页面,接下来去实现点击或打开功能。需要注意的是,微信打开红包需要两次点击,先是领取,然后打开,但是QQ只需要一次点击,微信红包较简单,只有一种类型,QQ红包类型有两种。所以我们应该在窗口变化之前监听是QQ还是微信发送过来的红包,然后根据不同的值去做不同的动作。
QQ红包
//检测到QQ红包 private void openQQHongBao(AccessibilityEvent event) { state_qq = STATE_NO_QQ; // getRunningActivityName(); if ("cooperation.qwallet.plugin.QWalletPluginProxyActivity".equals(event.getClassName())) { state_qq = STATE_OPENED_QQ; if (RBSharedPerences.readRBQQState(getApplicationContext(), STATE_CODE_QQ).equals(state_qq)) { performGlobalAction(GLOBAL_ACTION_HOME); RBSharedPerences.writeRBQQstate(getApplicationContext(), STATE_CODE_QQ, STATE_NO_QQ); } } else if ("com.tencent.mobileqq.activity.SplashActivity".equals(event.getClassName())) { //拆红包 state_qq = STATE_CLIECKED_QQ; openQQPacket(); } } //领取打开QQ红包 private void openQQPacket() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo != null) { AccessibilityNodeInfo targetNode = null; targetNode = findNodeInfosByText(nodeInfo, RB_BUTTON_TEXT_NAME); //普通红包 if (targetNode != null) { performClick(targetNode); RBSharedPerences.writeRBQQstate(getApplicationContext(), STATE_CODE_QQ, STATE_OPENED_QQ); } //口令红包 else { AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow(); if (accessibilityNodeInfo != null) { List<AccessibilityNodeInfo> nodeInfos = accessibilityNodeInfo .findAccessibilityNodeInfosByText(RB_PASSWORD); for (AccessibilityNodeInfo nodeInfo1 : nodeInfos) { targetNode = nodeInfos.get(nodeInfos.size() - 1); performClick(targetNode); writePassword(); } } } } } //写入并发送口令 private void writePassword() { AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow(); if (accessibilityNodeInfo != null) { findWidgetByText(accessibilityNodeInfo, RB_CLICK_TO_PASTE_PASSWORD); } if (accessibilityNodeInfo != null) { findWidgetByText(accessibilityNodeInfo, SEND_PASSWORD); RBSharedPerences.writeRBQQstate(getApplicationContext(), STATE_CODE_QQ, STATE_OPENED_QQ); } }
这里面有个巧妙的点,就是开始时我始终找不到红包RelativeLayout的ID,那可怎么办呢,我继续往外层查找,红包外层还是一层RelativeLayout,但是content-desc中的值是 “xxxx,点击查看详情”。
明白了吗?没错,我通过文本查找遇到有文字包含有这个时再去实现点击nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
那么口令红包又是如何实现的呢?同理,也是需要通过文本查找文字
但是这里直接查找”口令红包”就可以了,查找到后实现点击,QQ会自动给我们出现一个按钮在输入框上方
继续查找文本并点击”点击输入口令”,这时候,输入框就有口令了,那么查找到发送的文本再实现一次点击,红包就领取成功了。
微信红包
//检测到微信红包 private void openWeChatHongBao(AccessibilityEvent event) { state = STATE_NO; // getRunningActivityName(); if ("com.tencent.mm.ui.LauncherUI".equals(event.getClassName())) { //点中红包 getWeChatPacket(); } else if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI".equals(event.getClassName())) { //拆红包 openWeChatPacket(); } else if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI".equals(event.getClassName())) { state = STATE_OPENED; //拆完红包后返回 if (RBSharedPerences.readRBWeChatState(getApplicationContext(), STATE_CODE).equals(state)) { performGlobalAction(GLOBAL_ACTION_HOME); RBSharedPerences.writeRBWeChatState(getApplicationContext(), STATE_CODE, STATE_NO); } } } //领取红包 private void getWeChatPacket() { AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow(); if (accessibilityNodeInfo != null) { findWidgetByText(accessibilityNodeInfo, GET_RB_TEXT); } } //拆开红包 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private void openWeChatPacket() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo != null) { AccessibilityNodeInfo targetNode = null; targetNode = findNodeInfosByClassName(nodeInfo, RB_BUTTON_CLASS_NAME); performClick(targetNode); //设置值 RBSharedPerences.writeRBWeChatState(getApplicationContext(), STATE_CODE, STATE_OPENED); } }
微信的红包和QQ 不一样的地方在于需要先点开红包出现一个红包页面,再点击红包才会打开红包。点开红包查找文本”领取红包”并实现点击,这时页面进入”com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI”
这时候显然通过文本查找是不行的了,因为这里只是一个Button,并没有文字,所以说需要另辟蹊径,因为当前页面仅有这一个Button,所以我们可以通过控件具体名字查找控件。
//通过组件名字查找 public static AccessibilityNodeInfo findNodeInfosByClassName(AccessibilityNodeInfo nodeInfo, String className) { if (TextUtils.isEmpty(className)) { return null; } for (int i = 0; i < nodeInfo.getChildCount(); i++) { AccessibilityNodeInfo node = nodeInfo.getChild(i); if (className.equals(node.getClassName())) { return node; } } return null; }
再实现一个点击事件。perfect,微信红包领取成功。
一个抢红包功能就这么愉快的搞定了!!快去试试吧!!你的点赞是对我最好的支持!!谢谢!!
最后附上CSDN下载链接和github的链接
http://download.csdn.net/detail/a876980961/9723236
https://github.com/a876980961/pop_hongbao_assistant
相关文章推荐
- js实现微信/QQ直接跳转到支付宝APP打开口令领红包功能
- iOS实现微信/QQ显示最近拍摄图片的功能实例代码
- 微信抢红包微信 PHP代码实现
- 春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。
- [置顶] 微信文章webview记录上次访问位置的实现原理和代码,webview记录并定位到上次访问位置
- [置顶] 【Android】Listview返回顶部,快速返回顶部的功能实现,详解代码。
- QQ侧边栏功能简单实现,对初学者很适用,无序任何java代码即可实现
- jquery实现页面置顶功能代码
- 实现 微信/QQ聊天 发送位置功能
- Android仿ios微信左划条目删除、置顶的实现,代码简洁,更容易理解使用
- [置顶] 【Android】Scrollview返回顶部,快速返回顶部的功能实现,详解代码。
- php实现微信凭手气红包功能
- [置顶] 如何用php实现模拟微信抢红包
- 微信红包签名算法 C#代码实现
- Android (ListActivity、Contextmenu)微信类消息置顶和删除和功能的实现
- android抢红包代码解析支持微信与QQ
- 在个人网页中实现QQ在线联系的功能代码
- 用C#代码实现类似QQ窗体的“上、左、右”停靠功能
- 微信抢红包ASP.NET代码轻松实现
- 微信抢红包ASP.NET代码轻松实现