微信,QQ抢红包软件原理解析
生活随笔
收集整理的這篇文章主要介紹了
微信,QQ抢红包软件原理解析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
微信,QQ搶紅包軟件原理解析
目前市面上的搶紅包軟件都僅限于監聽通知欄確定紅包到來模擬點擊紅包,對于停留在qq聊天界面不能起作用,并且對于Android5.0,6,0版本更高的安全限制以及無法正常搶到紅包。本博客將介紹真正的搶紅包軟件,無論停留在qq消息界面,還是qq在后臺運行,均可以完美搶到紅包,并且支持口令紅包,以及口令消息的自動撤回功能。同時還將實現紅包消息到來時聊天窗口的自動切換功能,并且對Android5.0,6,0更高級別的安全限制做了適配。
搶紅包的原理主要利用Android中的輔助功能,不懂的可以自行百度也可參考博文 http://blog.csdn.net/feifei454498130/article/details/43891781 來模擬點擊,類似于按鍵精靈。
監聽紅包消息有兩種,一種是通過監聽通知欄(適用于退出qq,微信后臺運行的情況,另一種是通過監聽視圖的變化(適用于停留在當前聊天界面的情況)
話不多說,直接貼關鍵代碼:
代碼塊
/*** Created by 張建浩 on 15-11-6.*/ public class GetMoneyService extends AccessibilityService {private final static String TAG = GetMoneyService.class.getName();private Timer timer;private final static int PACKET_MM = 0;private final static int PACKET_QQ = 1;private boolean autoClick = false;private boolean autoClick2 = false;private boolean autoClickNotification = false;private int qqCommandPacketLock = 0;private int messageRevocation = 0;private int messageRevocation2 = 0;private String revocationMessage = null;private int inputMessageFlag = 0;private boolean canRevocation = false;//可信度private int confidenceLevel = 0;private int protectQQCommandLock = 0;private boolean willDeleteMessage = false;private boolean needCallbackMessage = false;public String getCurrentActivity(){if (android.os.Build.VERSION.SDK_INT<21){ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);List<ActivityManager.RunningTaskInfo> runningTasks = manager .getRunningTasks(1);ActivityManager.RunningTaskInfo cinfo = runningTasks.get(0);ComponentName component = cinfo.topActivity;return component.getClassName();}else if (android.os.Build.VERSION.SDK_INT<23) {return getCurrentPkgName(this);}elsereturn getProcessNew();}private String getProcessNew() {String topPackageName = null;UsageStatsManager usage = (UsageStatsManager)getSystemService(Context.USAGE_STATS_SERVICE);long time = System.currentTimeMillis();List<UsageStats> stats = usage.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time);if (stats != null) {SortedMap<Long, UsageStats> runningTask = new TreeMap<Long,UsageStats>();for (UsageStats usageStats : stats) {runningTask.put(usageStats.getLastTimeUsed(), usageStats);}if (runningTask.isEmpty()) { // Log.v(TAG,"running tast is empty");return null;}topPackageName = runningTask.get(runningTask.lastKey()).getPackageName();}return topPackageName;}public String getCurrentPkgName(Context context) {ActivityManager.RunningAppProcessInfo currentInfo = null;Field field = null;int START_TASK_TO_FRONT = 2;String pkgName = null;try {field = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");} catch (Exception e) { e.printStackTrace(); }ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List<ActivityManager.RunningAppProcessInfo> appList = am.getRunningAppProcesses();for (ActivityManager.RunningAppProcessInfo app:appList) {if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {Integer state = null;try {state = field.getInt( app );} catch (Exception e) { e.printStackTrace(); }if (state != null && state == START_TASK_TO_FRONT) {currentInfo = app;break;}}}if (currentInfo != null) {pkgName = currentInfo.processName;}return pkgName;// ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); // // List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses(); // // Log.i(TAG,"current_app"+tasks.get(0).processName); // return tasks.get(0).processName;}@Overrideprotected void onServiceConnected() {super.onServiceConnected();Log.v(TAG, "服務已連接");AccessibilityServiceInfo info = getServiceInfo();info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;info.packageNames = new String[]{"com.tencent.mm", "com.tencent.mobileqq"};setServiceInfo(info);qqCommandPacketLock = 0;needCallbackMessage = SharePreferenceUtils.getBooleanValue(getApplicationContext(),"message","can_callback_message"); // Log.v(TAG,"need callback:"+needCallbackMessage); // timer = new Timer(); // timer.schedule(new TimerTask() { // @Override // public void run() { // Log.v(TAG,"current acitivity:"+getCurrentActivity()); // } // },0,2000);}@Overridepublic void onAccessibilityEvent(AccessibilityEvent event) {int eventType = event.getEventType();confidenceLevel = 0;canRevocation = false;Log.v(TAG,"回調了");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(TAG, "text:"+content);if (content.contains(Constant.MM_LUCKY_MONEY)||content.contains(Constant.QQ_LUCKY_MONEY)) {//模擬打開通知欄消息if (event.getParcelableData() != null&&event.getParcelableData() instanceof Notification) {Notification notification = (Notification) event.getParcelableData();PendingIntent pendingIntent = notification.contentIntent;try {String currentApp = getCurrentActivity();if (currentApp != null && currentApp.matches("com.\\w+launcher\\w+")){}autoClickNotification = true;pendingIntent.send();} catch (Exception e) {e.printStackTrace();}}}}}break;//第二步:監聽是否進入紅包消息界面case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:String className = event.getClassName().toString();Log.v(TAG,"class name:"+className);switch (className){case "com.tencent.mm.ui.LauncherUI"://開始搶紅包Log.v(TAG,"開始尋找微信紅包");if (autoClickNotification)getPacket(PACKET_MM);break;case "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI"://開始打開紅包 // Log.v(TAG,"準備打開微信紅包啦");openPacket();break;case "com.tencent.mobileqq.activity.SplashActivity": // Log.v(TAG,"開始進入qq界面");qqCommandPacketLock = 0;recycle(getRootInActiveWindow(),Constant.QQ_LUCKY_MONEY);getPacket(PACKET_QQ);break;case "cooperation.qwallet.plugin.QWalletPluginProxyActivity":qqCommandPacketLock = 0;if (messageRevocation == 1)messageRevocation ++;Log.v(TAG,"出現了窗口");if (autoClick) {performGlobalAction(GLOBAL_ACTION_BACK);autoClick = false;if (autoClickNotification) {performGlobalAction(GLOBAL_ACTION_HOME); // performGlobalAction(GLOBAL_ACTION_RECENTS);autoClickNotification = false;}}break;}break;case AccessibilityEvent.TYPE_VIEW_SCROLLED:// if ("com.tencent.mm.ui.LauncherUI".contains(getCurrentActivity())) // getPacket(PACKET_MM); // else if ("com.tencent.mobileqq.activity.SplashActivity".contains(getCurrentActivity())){ // getPacket(PACKET_QQ); // }break;default:Log.v(TAG,"content update:"+getCurrentActivity());String currentActivity = getCurrentActivity(); // getPacket(PACKET_QQ); // getPacket(PACKET_MM); // Log.v (TAG,"current contain:"+(currentActivity!= null&¤tActivity.contains("com.tencent.mobileqq.activity"))); // if ("com.tencent.mm.ui.LauncherUI".contains(currentActivity)) { // getPacket(PACKET_MM); // }if ("com.tencent.mobileqq.activity.SplashActivity".contains(currentActivity)||(currentActivity!= null&¤tActivity.contains("com.tencent.mobileqq.activity"))){getPacket(PACKET_QQ);}break;}}/*** 查找到*/private void openPacket() {AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();if (nodeInfo != null) {autoClickNotification = false;recycle(nodeInfo, Constant.MM_GET_PACKET);}}private void getPacket(int type) {AccessibilityNodeInfo rootNode = getRootInActiveWindow();if (type == PACKET_MM)recycle(rootNode, Constant.MM_LUCKY_MONEY2);else if (type == PACKET_QQ)recycle(rootNode,Constant.QQ_GET_PACKET);}private void recycle(AccessibilityNodeInfo info,String keywords) {if (info != null){if (info.getChildCount() == 0) {if(info.getText() != null){Log.v(TAG,"qqcommandLock:"+qqCommandPacketLock+"protectlock"+protectQQCommandLock);Log.v(TAG,info.getText().toString());String uitext = info.getText().toString();if (inputMessageFlag == 1){ // Log.v(TAG,"獲取到輸入的文本3:"+uitext);revocationMessage = uitext;inputMessageFlag = 0;}if (uitext.equals(getString(R.string.copy))||uitext.equals(getString(R.string.forward))||uitext.equals(getString(R.string.collect))||uitext.equals(getString(R.string.delete))){//識別關鍵字可信度confidenceLevel++; // Log.v(TAG,"confidence:"+confidenceLevel);}if (needCallbackMessage&&uitext.equals(getString(R.string.delete))){//可信度大于等于3并且不可撤回,if (confidenceLevel>=3 && !canRevocation&& messageRevocation2 >= 1){ // performGlobalAction(GLOBAL_ACTION_BACK);messageRevocation2++;info.performAction(AccessibilityNodeInfo.ACTION_CLICK);}else if (messageRevocation2 >=2){messageRevocation2 = 0;autoClickNodeInfo(info);} // Log.v(TAG,"messageRevocaton2:"+messageRevocation2+" confidence:"+confidenceLevel+"canrevocation"+canRevocation);//是刪除并且要刪除信息}if(keywords.equals(info.getText().toString())){//這里有一個問題需要注意,就是需要找到一個可以點擊的ViewLog.i("demo", "Click" + ",isClick:" + info.isClickable());autoClick = true;autoClickNodeInfo(info);}else if (uitext.contains(Constant.QQ_LUCKY_MONEY) && !uitext.equals(Constant.QQ_LUCKY_MONEY)){autoClickNodeInfo(info);}else if ((qqCommandPacketLock ==0&& Constant.QQ_COMMAND_PACKET.equals(info.getText().toString()))){//點擊拆開qqCommandPacketLock = 1;protectQQCommandLock = 0;//防止死鎖變量autoClick = true;autoClickNodeInfo(info);}else if (qqCommandPacketLock == 1&&Constant.QQ_PACKET_COMMAND_INPUT.equals(uitext)){qqCommandPacketLock = 2;inputMessageFlag = 1;protectQQCommandLock = 1;autoClick = true;autoClickNodeInfo(info);}else if (qqCommandPacketLock == 2 && getString(R.string.send).equals(info.getText().toString())){qqCommandPacketLock = 0;protectQQCommandLock = 0;messageRevocation = 1;autoClick = true;autoClickNodeInfo(info);}else if (messageRevocation >1&&info.getText().toString().equals(revocationMessage)){if (needCallbackMessage){messageRevocation2 ++;info.performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);}}else if (messageRevocation >=1&&getString(R.string.revocation).equals(uitext)){if (needCallbackMessage){canRevocation = true;messageRevocation = -1;info.performAction(AccessibilityNodeInfo.ACTION_CLICK);}}else if (messageRevocation <0 && getString(R.string.confirm).equals(info.getText().toString())){messageRevocation = 0;info.performAction(AccessibilityNodeInfo.ACTION_CLICK);}}} else {for (int i = 0; i < info.getChildCount(); i++) {if(info.getChild(i)!=null){recycle(info.getChild(i),keywords);}}}}}private void autoClickNodeInfo(AccessibilityNodeInfo info) {autoClick = true;if (info.isClickable())info.performAction(AccessibilityNodeInfo.ACTION_CLICK);else {AccessibilityNodeInfo parent = info.getParent();while(parent != null){ // Log.i("demo", "parent isClick:"+parent.isClickable());if(parent.isClickable()){autoClick = true;parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);break;}parent = parent.getParent();}}}@Overridepublic void onInterrupt() {if (timer != null){timer.cancel();timer = null;}} }/*** Created by 張建浩 on 15-11-6.*/ public class Constant {public final static String MM_LUCKY_MONEY = "[微信紅包]";public final static String MM_LUCKY_MONEY2 = "微信紅包";public final static String MM_GET_PACKET = "拆紅包";public final static String QQ_LUCKY_MONEY = "[QQ紅包]";public final static String QQ_GET_PACKET = "點擊拆開";public final static String QQ_COMMAND_PACKET = "口令紅包";public final static String QQ_PACKET_COMMAND_INPUT = "點擊輸入口令";}代碼比較多,這里只貼了搶紅包服務的關鍵代碼,讀者可自行修改。軟件下載地址:http://download.csdn.net/detail/u013454746/9421612
總結
以上是生活随笔為你收集整理的微信,QQ抢红包软件原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: R语言 下载文件
- 下一篇: LeetCode—209. 长度最小的子