安卓微信自動搶紅包外掛優化和實現
轉載請註明作者AndroidMSky和連結http://blog.csdn.net/AndroidMsky/article/details/53490459
又是興趣系列
網上有很多自動強紅包的例子和程式碼,筆者也是做了一些優化。
先說說自己的兩個個優勢
1.可以在聊天介面自動強不依賴於通知欄推送
2.可以在螢幕熄滅的時候的時候點亮螢幕自動搶(目前只測過flyme)
先上圖:
微信6.5.3體驗APK( 目前部分新款6.0.1手機不可用。無法識別推送)
通過對6.0.1 MIUI的小米max進行測試發現微信6.5.3採用的通知欄並不是標準的通知欄。
通過:
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
是無法檢測到紅包通知的。
而使用安卓5.0.1 Flyme os 4.5.7A的MX2 可以監聽到通知,並正確開啟紅包,大膽想象:最新版本的微信對通知進行了處理,如果第三方ROM支援這種自己開發的通知欄(非原聲通知欄)那麼微信就使用這種通知欄進行訊息的通知,我們的AccessibilityService就難以監控到了,如果ROM沒有自己開發的通知欄,那麼還用系統的通知欄,那麼就可以監控的到並正確強紅包,目前看如果想強紅包的還是建議暫時不要升級6.5.3
回到正題
原理:
通過AccessibilityService監聽到狀態列通知,進行模擬點選,獲取螢幕中view節點為領取紅包的list並且點選最後一個。
如果不通過狀態列通知,通過檢視變化AccessibilityEvent的2048事件也是就
public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
每次接受到新訊息都會有這個時間的回撥:
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventType = event.getEventType();
if (auto)
Log.e("AAAAAAAA", "有事件" + eventType);
switch (eventType) {
//當通知欄發生改變時
case 2048:
pubclassName = event.getClassName().toString();
Log.e("AAAAAAAA", "有2048事件" + pubclassName + auto);
if (!auto && pubclassName.equals("android.widget.TextView") && ALL) {
Log.e("AAAAAAAA", "有2048事件被識別" + auto + pubclassName);
getLastPacket(1);
}
if (auto && WXMAIN) {
getLastPacket();
auto = false;
}
break;
所以在接受的時候,去處理一下去點選領取紅包。然而這個方法會被頻發呼叫,我們就加一個”android.widget.TextView”事件類的篩選,然後還是會被很頻繁呼叫,會比較遲效能耗電。
那就加個布林ALL標誌位,讓使用者控制是否開啟聊天介面內也搶紅包的模式。
為了不反覆領取要記錄上次介面內的紅包數量在紅包增加的時候才去領取:
private void getLastPacket(int c) {
Log.e("AAAAAAAA", "新方法" + parents.size());
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
recycle(rootNode);
Log.e("AAAAAAAA", "last++" + lastbagnum + "當前頁面紅包數" + parents.size());
if (parents.size() > 0 && WXMAIN) {
Log.e("AAAAAAAA", "頁面大於O且在微信介面");
if (lastbagnum < parents.size())
parents.get(parents.size() - 1).performAction(AccessibilityNodeInfo.ACTION_CLICK);
lastbagnum = parents.size();
parents.clear();
}
}
目前在通過外掛領過幾個紅包後,一個聊天介面突然發第一個紅包(沒有通知欄)會有一定機率領取不到,再繼續發就正常了,應該是清空問題,該bug筆者也在更改邏輯中。
點亮螢幕方法(有密碼肯定是不行的):
private void wakeAndUnlock2(boolean b)
{
if(b)
{
//獲取電源管理器物件
pm=(PowerManager) getSystemService(Context.POWER_SERVICE);
//獲取PowerManager.WakeLock物件,後面的引數|表示同時傳入兩個值,最後的是除錯用的Tag
wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
//點亮螢幕
wl.acquire();
//得到鍵盤鎖管理器物件
km= (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
kl = km.newKeyguardLock("unLock");
//解鎖
kl.disableKeyguard();
}
else
{
//鎖屏
kl.reenableKeyguard();
//釋放wakeLock,關燈
wl.release();
}
}
接受到通知欄的紅包訊息亮屏設定標誌位為自動領取,調取領取函式:
if (content.contains("[微信紅包]")) {
if (event.getParcelableData() != null &&
event.getParcelableData() instanceof Notification) {
Notification notification = (Notification) event.getParcelableData();
PendingIntent pendingIntent = notification.contentIntent;
try {
auto = true;
wakeAndUnlock2(true);
pendingIntent.send();
Log.e("demo", "進入微信" + auto + event.getClassName().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
點選介面控制元件方法:(不同微信版本控制元件id不一樣我的是6.3.25)如果不知道怎麼獲取這個id可以看下面的參考文獻最後一個,右側的resource-id就是這個id
順便說一下目前微信
6.3.31開紅包按鈕的id是com.tencent.mm:id/bg7換成這個就好了
6.3.32開紅包按鈕的id是com.tencent.mm:id/bdh換成這個就好了
6.5.3版本(1月13號最新版本)
com.tencent.mm:id/be_ 換成這個就好了
目前不知道什麼問題,在6.5.3下有一些手機無法監控到紅包推送的通知,我也正在修復中。穩定版本6.3.32仍然可用。
。
click("com.tencent.mm:id/be_");
好多同學還是不懂如何獲取id,我再上個詳細的圖:
顯示選擇這裡:
然後:
在Activity中設定聊天中領取開關:
public void start(View v) {
if (AirAccessibilityService.ALL) {
AirAccessibilityService.ALL = false;
((Button) v).setText("對話內監控+關");
} else {
AirAccessibilityService.ALL = true;
((Button) v).setText("對話內監控+開");
}
;
}
AccessibilityService的確很吊,你用AccessibilityService或者root後的安卓手機能幹太多事了,或好或壞,但畢竟技術是無罪的。
歡迎關注作者。歡迎評論討論。歡迎拍磚。 如果覺得這篇文章對你有幫助,歡迎打賞, 歡迎star,Fork我的github。 喜歡作者的也可以Follow。也算對作者的一種支援。 本文Github程式碼連結
https://github.com/AndroidMsky/WXhongbao