Android微信/QQ紅包自動搶(AccessibilityService)
關於搶紅包的文章已經很多了,我再來總結下,QQ的順便也實現下,原理很簡單,搜尋螢幕中的文字,搜尋到了就點選,QQ相對來說要簡單一些
關鍵程式碼:
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
nodeInfo.findAccessibilityNodeInfosByText("恭喜");
首先,在輔助功能裡面開啟服務後,onAccessibilityEvent方法會接受到一些事件,我們來看看常用的一些事件
public class Types{
final class types {
//所有事件
public static final int types_all_mask = -1;
//通知欄
public static final int type_notification_state_changed = 64;
//點選事件
public static final int type_view_clicked = 1;
//控制元件獲取焦點
public static final int type_view_focused = 8;
//長按事件
public static final int type_view_long_clicked = 2;
//頁面變動
public static final int type_view_scrolled = 4096;
//控制元件選中
public static final int type_view_selected = 4;
//輸入框文字改變
public static final int type_view_text_changed = 16;
//輸入框文字selection改變
public static final int type_view_text_selection_changed = 8192;
//視窗內容改變
public static final int type_window_content_changed = 2048;
//視窗狀態改變
public static final int type_window_state_changed = 32;
}
}
typeAllMask代表可以監聽到所有的事件,我們這次只用到typeNotificationStateChanged和typeWindowStateChanged,還有typeWindowContentChanged
下面開始具體程式碼
1、建立Service
WXEnvelopeService.java
package com.zx.redenvelopes;
import android.accessibilityservice.AccessibilityService;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Instrumentation;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.PowerManager;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static android.content.ContentValues.TAG;
//文字型別:
// 微信text==童鞋: 恭喜發財
//紅包型別:
// 微信text==童鞋: [微信紅包]恭喜發財,大吉大利
public class WXEnvelopeService extends AccessibilityService {
static final String ENVELOPE_TEXT_KEY = "[微信紅包]";
@SuppressLint("NewApi")
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
//Log.d(TAG, "微信事件--------------------------" + event.getEventType());
//通知欄事件
if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
List<CharSequence> texts = event.getText();
if (!texts.isEmpty()) {
for (CharSequence t : texts) {
String text = String.valueOf(t);
Log.v("tag", "監控微信訊息==" + text);
if (text.contains(ENVELOPE_TEXT_KEY)) {
openNotification(event);
break;
}
}
}
} else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
openEnvelope(event);
} else if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
openEnvelopeContent(event);
}
}
/**
* 開啟通知欄訊息並跳轉到紅包頁面
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
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();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void openEnvelope(AccessibilityEvent event) {
if ("com.tencent.mm.ui.LauncherUI".equals(event.getClassName())) {
checkKeyFirst();
} else if ("com.tencent.mm.plugin.luckymoney.ui.En_fba4b94f".equals(event.getClassName())) {
checkOpen();
} else if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI".equals(event.getClassName())) {
//Toast.makeText(this, "紅包已經搶完--------", Toast.LENGTH_SHORT).show();
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void openEnvelopeContent(AccessibilityEvent event) {
if ("android.widget.TextView".equals(event.getClassName())) {
checkKeyFirst();
} else if ("com.tencent.mm.plugin.luckymoney.ui.En_fba4b94f".equals(event.getClassName())) {
checkOpen();
} else if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI".equals(event.getClassName())) {
// Toast.makeText(this, "紅包已經搶完--------", Toast.LENGTH_SHORT).show();
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void checkOpen() {
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
if (nodeInfo == null) {
return;
}
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("恭喜");
for (int i = list.size() - 1; i >= 0; i--) {
AccessibilityNodeInfo parent = list.get(i).getParent();
for (int j = 0; j < parent.getChildCount(); j++) {
AccessibilityNodeInfo child = parent.getChild(j);
if (child != null && child.isClickable()) {
child.performAction(AccessibilityNodeInfo.ACTION_CLICK);
break;
}
}
}
}
private void checkKeyFirst() {
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
if (nodeInfo == null) {
return;
}
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("領取紅包");
if (list.isEmpty()) {
return;
}
for (int i = list.size() - 1; i >= 0; i--) {
AccessibilityNodeInfo parent = list.get(i).getParent();
if (parent != null) {
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
break;
}
}
}
@Override
public void onInterrupt() {
Toast.makeText(this, "微信搶紅包服務已關閉", Toast.LENGTH_SHORT).show();
}
@Override
protected void onServiceConnected() {
super.onServiceConnected();
Toast.makeText(this, "微信搶紅包服務已開啟", Toast.LENGTH_SHORT).show();
}
}
QQEnvelopeService.java
package com.zx.redenvelopes;
import android.accessibilityservice.AccessibilityService;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;
import java.util.List;
import static android.content.ContentValues.TAG;
//文字型別:
// 監控QQ訊息==童鞋: 恭喜發財
//紅包型別:
// 監控QQ訊息==童鞋: [QQ紅包]恭喜發財
public class QQEnvelopeService extends AccessibilityService {
static final String ENVELOPE_TEXT_KEY = "[QQ紅包]";
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(TAG, "QQ事件--------------------------" + event.getEventType());
final int eventType = event.getEventType();
if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
List<CharSequence> texts = event.getText();
if (!texts.isEmpty()) {
for (CharSequence t : texts) {
String text = String.valueOf(t);
Log.v("tag", "監控QQ訊息==" + text);
if (text.contains(ENVELOPE_TEXT_KEY)) {
openNotification(event);
break;
}
}
}
} else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
openEnvelope(event);
} else if(eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
openEnvelopeContent(event);
}
}
/**
* 開啟通知欄訊息並跳轉到紅包頁面
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
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();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void openEnvelope(AccessibilityEvent event) {
if ("com.tencent.mobileqq.activity.SplashActivity".equals(event.getClassName())) {
checkKey();
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void openEnvelopeContent(AccessibilityEvent event) {
/*if ("android.widget.RelativeLayout".equals(event.getClassName())) {
checkKey();
} else if("android.widget.TextView".equals(event.getClassName())) {
checkKey();
}*/
checkKey();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void checkKey() {
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
if (nodeInfo == null) {
return;
}
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("點選拆開");
if (list.isEmpty()) {
return;
}
for (AccessibilityNodeInfo info : list) {
AccessibilityNodeInfo parent = info.getParent();
if (parent != null) {
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
break;
}
}
}
@Override
public void onInterrupt() {
Toast.makeText(this, "QQ搶紅包服務已關閉", Toast.LENGTH_SHORT).show();
}
@Override
protected void onServiceConnected() {
super.onServiceConnected();
Toast.makeText(this, "QQ搶紅包服務已開啟", Toast.LENGTH_SHORT).show();
}
}
2、建立對應的xml
res/xml/envelope_service_config_qq.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 關鍵是android:accessibilityEventTypes="typeAllMask", typeAllMask代表監聽所有的事件,這邊不寫的話,AccessibilityService就接收不到 -->
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagRequestFilterKeyEvents"
android:canRetrieveWindowContent="true"
android:canRequestFilterKeyEvents="true"
android:description="@string/accessibility_description"
android:notificationTimeout="100"
android:packageNames="com.tencent.mobileqq" />
res/xml/envelope_service_config_wx.xml
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowContentChanged|typeNotificationStateChanged|typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagRequestFilterKeyEvents"
android:canRetrieveWindowContent="true"
android:canRequestFilterKeyEvents="true"
android:description="@string/accessibility_description"
android:notificationTimeout="100"
android:packageNames="com.tencent.mm" />
3、AndroidManifest.xml中註冊
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zx.redenvelopes">
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_app"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:enabled="true"
android:exported="true"
android:label="QQ自動搶紅包服務"
android:name=".QQEnvelopeService"
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/envelope_service_config_qq"/>
</service>
<service
android:enabled="true"
android:exported="true"
android:label="微信自動搶紅包服務"
android:name=".WXEnvelopeService"
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/envelope_service_config_wx"/>
</service>
</application>
</manifest>
最後開啟服務的程式碼如下:
//開啟系統設定中輔助功能
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(intent);
Toast.makeText(MainActivity.this, "找到微信/QQ自動搶紅包服務,開啟即可", Toast.LENGTH_LONG).show();
相關推薦
Android微信/QQ紅包自動搶(AccessibilityService)
關於搶紅包的文章已經很多了,我再來總結下,QQ的順便也實現下,原理很簡單,搜尋螢幕中的文字,搜尋到了就點選,QQ相對來說要簡單一些 關鍵程式碼: AccessibilityNodeInfo nodeInfo = getRootInActiveWindow
微信小程式之仿android fragment之可滑動的底部導航欄例項 —— 微信小程式實戰系列(4)
底部3-5個選項的底部導航欄,目前在移動端上是主流佈局之一 因此騰訊官方特地做了,可以通過設定,就可以做出了一個底部的導航欄 但是通過設定的這個底部的導航欄,功能上比較固定,它必須要設定與它對應的一個頁面,而且並不能滑動。 在業務上,有時候會比較限制,並不能完全滿足所需
微信公眾平臺開發者模式(2)JAVA自動回覆文字訊息及多圖文訊息
資料流向 使用者<———–>微信端 <———–>後臺伺服器 成功接入微信端後 接受微信端傳送的xml訊息,解析為實體物件,處理後再轉成xml格式的資料傳送給微信端 servlet程式碼 public void doPost
Android簡單實現仿微信選擇圖片以及拍照(PhotoPicker)
實現仿微信的圖片選擇,預覽以及拍照,屬性可以設定顯示照相機以及預覽時是否顯示刪除按鈕等,功能齊全並且可以根據儲存照片的路徑進行修改等 Gradle配置 dependencies { co
Python-快速實現微信公眾號自動回覆(聊天機器人)
原理:通過微信公眾號提供的開發者模式,利用Python搭建環境,實現自動回覆,回覆內容通過呼叫圖靈機器人的API 配置:伺服器(這裡是阿里雲主機,Ubuntu),公眾號,圖靈機器人 一,公眾平臺上進行開發配置 三種加密方式,按需選擇。第一種最簡單,最不安全(我這裡選擇的第
微信小程序 支付功能(前端)的實現
pen 回退 ole pack spa session 統一支付 ges 應用 只提供微信小程序端代碼: 1 var app = getApp(); 2 Page({ 3 data: {}, 4 onLoad: function (options) {
微信小程序訪問webService(Java)
微信小程序解析xml 微信小程序調用java(wsdl) 在前臺UI確認後,終於進入到後臺服務的搭建及實現中。所及而來的問題就出現了,為了提高後臺程序的可用性。設計初期決定,通過搭建java WebService實現。準備工作還是比較充分的,創建WebService框架,實現接口方法。通過建立測試客戶端
微信小程序開發教程(八)視圖層——.wxml詳解
span hid 處理 路徑 strong 一般來說 emp 條件 頁面數據 框架的視圖層由WXMKL(WeiXin Markup language)與WXSS(WeiXin Style Sheet)編寫,由組件進行展示。 對於微信小程序而言,視圖層就是所有.wxm
微信小程序開發教程(九)視圖層——.wxss詳解
hone mnt 而且 padding 移動 圖層 組成 特性 -1 WXSS是一套樣式語言,用於描述WXML的組件樣式。 官方文檔表示,WXSS的選擇器目前支持(“.class”、“#id”、“elemnt”、“element,element”、“::after”
微信公眾平臺開發教程(三) 基礎框架搭建
開發 images wxs user 設計實現 bytes trre 來源 app 上一章,我們已經初步講解了微信公眾賬號開發的基本原理,今天我們來探索設計實現。 首先我們設計了模塊層次圖,當然圖中只是給出一種實現方式,不局限於此。具體見下圖。 主要功能介紹如下: 1)請求
微信公眾平臺開發教程(一) 微信公眾賬號註冊流程
身份證 logs 政府 提交 註意 bsp 訪問服務器 定義 htm 具體的操作步驟 1、註冊公眾賬號 註冊地址:http://mp.weixin.qq.com/ 1)首先需要郵箱註冊: 2)郵箱激活。郵箱將會收到激活郵件,點擊激活鏈接即可。 3)需要登記個人信息。這裏需
微信公眾平臺開發教程(八)Session處理
class 如果 obj returns name ref car opera 信用 在微信窗口,輸入的信息有限,我們需要將一些信息分多次請求。 比如:在進行用戶綁定時,我們需要輸入用戶的相關信息,比如:用戶名、密碼,或者姓名、電話號碼,服務端驗證通過,即可將系統用戶與微信
微信公眾平臺開發教程(十) 訂閱號與服務號的區別
接口文檔 lpad 手機 全部 oauth2.0 spa 上傳 ima lsp 為了消除大家對訂閱號與服務號的疑問,特總結如下: 功能點 介紹 訂閱號 服務號 註冊 註冊賬號 個人信息 個人信息和企業相關信息 展示 在
微信公眾平臺開發教程(二) 基本原理及消息接口
username 普通用戶 縮放 地理位置 cfb 位置 註意 獲得 基本 一、基本原理 在開始做之前,大家可能對這個很感興趣,但是又比較茫然。是不是很復雜?很難學啊? 其實恰恰相反,很簡單。為了打消大家的顧慮,先簡單介紹了微信公眾平臺的基本原理。 微信服務器就相當於一個轉
微信公眾平臺開發教程(五)自定義菜單
打開鏈接 delete toolbar 推送 優化 pcl reader 接口查詢 robot 應大家強烈要求,將自定義菜單功能課程提前。 一、概述: 如果只有輸入框,可能太簡單,感覺像命令行。自定義菜單,給我們提供了很大的靈活性,更符合用戶的操作習慣。在一個小小的微信對話
微信小程序——豆瓣電影——(2):小程序運行部署
images 放心 覆蓋 當前 .cn markup 必須 global 定義 Demo 預覽 演示視頻(流量預警 2.64MB) GitHub Repo 地址 倉庫地址:https://github.com/zce/weapp-demo 使用步驟 將倉庫克隆到本地
[轉]微信小程序之加載更多(分頁加載)實例 —— 微信小程序實戰系列(2)
是否 底部 watermark water ongl 小程序教程 所有 空數組 osi 本文轉自;http://blog.csdn.net/michael_ouyang/article/details/56846185 loadmore 加載更多(分頁加載) 當
微信小程序的開發(一)
ram tle ati java ndt 喜歡 top lex navig 我現在在學習,微信小程序開發,剛剛看看一篇對我特別有用的博客文章,我就把摘抄過來了,好好的學習一下。 序言 開始開發應用號之前,先看看官方公布的「小程序」教程吧!(以下內容來自微信官方公布的「小程序
微信消息加解密(GoLang)-- 接收和回復加密消息
too simple 更改 chatapp body sge and print news 接收微信消息的接口內容: //"r"為*http.Request r.ParseForm() timestamp := strings.Join(r.For
如何利用Python網絡爬蟲抓取微信朋友圈的動態(上)
Python 網絡爬蟲 微信 朋友圈 Python開發 今天小編給大家分享一下如何利用Python網絡爬蟲抓取微信朋友圈的動態信息,實際上如果單獨的去爬取朋友圈的話,難度會非常大,因為微信沒有提供向網易雲音樂這樣的API接口,所以很容易找不到門。不過不要慌,小編在網上找到了第三方工具,它可