亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

教你一步步實現(xiàn)Android微信自動搶紅包

 更新時間:2016年08月28日 11:41:09   作者:oden  
自從微信添加搶紅包的功能,微信的電商之旅算是正式開始正式火爆起來。但是作為Android開發(fā)者來說,我們首先考慮的是如何實現(xiàn)Android微信自動搶紅包呢,下面我們來一起看看吧。

本文介紹微信自動搶紅包的實現(xiàn)方法,主要實現(xiàn)以下幾個功能:

      1.自動拆開屏幕上出現(xiàn)的紅包

      2.處于桌面或聊天列表時接收到紅包信息時自動進入聊天界面并拆紅包

      3.日志功能,記錄搶紅包的詳細日志

實現(xiàn)原理

     1.利用AccessibilityService輔助服務(wù),監(jiān)測屏幕內(nèi)容,實現(xiàn)自動拆紅包的目的。

     2.利用ActiveAndroid數(shù)據(jù)庫簡單記錄紅包日志

     3.利用preference實現(xiàn)監(jiān)控選項紀錄

最終界面

搶紅包核心代碼

AccessibilityService配置

android:accessibilityEventTypes 設(shè)置觸發(fā)監(jiān)聽回調(diào)的事件類型;

android:packageNames 設(shè)置監(jiān)聽的應(yīng)用,這里監(jiān)聽的是微信,因此填上微信的包名com.tencent.mm

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged|typeWindowContentChanged"
 android:accessibilityFeedbackType="feedbackGeneric"
 android:accessibilityFlags="flagDefault"
 android:canRetrieveWindowContent="true"
 android:description="@string/accessibility_description"
 android:notificationTimeout="100"
 android:packageNames="com.tencent.mm"
 android:settingsActivity="com.oden.annotations.app.activity.ManActivity" />

在AndroidManifest.xml中聲明:

 <service
   android:name=".app.service.HongbaoService_"
   android:enabled="true"
   android:exported="true"
   android:label="@string/app_name"
   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/accessibility_service_config" />
  </service>

搶紅包實現(xiàn)代碼

接收系統(tǒng)發(fā)送來的AccessibilityEvent

 private static final String GET_RED_PACKET = "領(lǐng)取紅包";
 private static final String CHECK_RED_PACKET = "查看紅包";
 private static final String RED_PACKET_PICKED = "手慢了,紅包派完了";
 private static final String RED_PACKET_PICKED2 = "手氣";
 private static final String RED_PACKET_PICKED_DETAIL = "紅包詳情";
 private static final String RED_PACKET_SAVE = "已存入零錢";
 private static final String RED_PACKET_NOTIFICATION = "[微信紅包]";

 @Override
 public void onAccessibilityEvent(AccessibilityEvent event) {
  L.d("RECEIVE EVENT!");
  if (watchedFlags == null) return;
   /* 檢測通知消息 */
  if (!mMutex) {
   if (watchedFlags.get("pref_watch_notification") && watchNotifications(event)) return;
   if (watchedFlags.get("pref_watch_list") && watchList(event)) return;
  }
  if (!watchedFlags.get("pref_watch_chat")) return;

  this.rootNodeInfo = event.getSource();
  if (rootNodeInfo == null) return;

  mReceiveNode = null;
  mUnpackNode = null;

  checkNodeInfo();

   /* 如果已經(jīng)接收到紅包并且還沒有戳開 */
  if (mLuckyMoneyReceived && !mLuckyMoneyPicked && (mReceiveNode != null)) {
   mMutex = true;
   AccessibilityNodeInfo cellNode = mReceiveNode;
   cellNode.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
   mLuckyMoneyReceived = false;
   mLuckyMoneyPicked = true;
   L.d("正在打開!");
  }

   /* 如果戳開但還未領(lǐng)取 */
  if (mNeedUnpack && (mUnpackNode != null)) {
   AccessibilityNodeInfo cellNode = mUnpackNode;
   cellNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
   mNeedUnpack = false;
   L.d("正在領(lǐng)??!");
  }

  if (mNeedBack) {
   performGlobalAction(GLOBAL_ACTION_BACK);
   mMutex = false;
   mNeedBack = false;
   L.d("正在返回!");
   //總次數(shù)和金額統(tǒng)計
   if (isGetMoney) {
    T.showShort(this, "搶到一個紅包: " + gotMoney + "元!");
    totalMoney = totalMoney + gotMoney;
    totalSuccessNum++;
    myPrefs.totalMoney().put(totalMoney);
    myPrefs.successNum().put(totalSuccessNum);
    L.d("totalMoney: " + totalMoney);
    L.d("totalSuccessNum: " + totalSuccessNum);
    saveToLog(hongbaoInfo);
    isGetMoney = false;
   }
  }
 }

檢測監(jiān)聽事件的節(jié)點信息

private void checkNodeInfo() {
  L.d("checkNodeInfo!");
  if (this.rootNodeInfo == null) return;
   /* 聊天會話窗口,遍歷節(jié)點匹配“領(lǐng)取紅包”和"查看紅包" */
  List<AccessibilityNodeInfo> nodes1 = this.findAccessibilityNodeInfosByTexts(this.rootNodeInfo, new String[]{
    GET_RED_PACKET, CHECK_RED_PACKET});
  if (!nodes1.isEmpty()) {
  L.d("!nodes1.isEmpty()");
   AccessibilityNodeInfo targetNode = nodes1.get(nodes1.size() - 1);
   if ("android.widget.LinearLayout".equals(targetNode.getParent().getClassName()))//避免被文字干擾導(dǎo)致外掛失效
   {
    if (this.signature.generateSignature(targetNode)) {
     mLuckyMoneyReceived = true;
     mReceiveNode = targetNode;
     L.d("signature:" + this.signature.toString());
    }
   } else {
    L.d("this is text");
   }
   return;
  }

  List<AccessibilityNodeInfo> nodes2 = this.findAccessibilityNodeInfosByTexts(this.rootNodeInfo, new String[]{
    "拆紅包"});
  if (!nodes2.isEmpty()) {
   L.d("node2 != null");
   for (AccessibilityNodeInfo nodeInfo : nodes2) {
     if (nodeInfo.getClassName().equals("android.widget.Button"))
      nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
   }
  } else {
    /* 戳開紅包,紅包還沒搶完,遍歷節(jié)點匹配“拆紅包” */
   AccessibilityNodeInfo node2 = (this.rootNodeInfo.getChildCount() > 3) ? this.rootNodeInfo.getChild(3) : null;
   if (node2 != null && node2.getClassName().equals("android.widget.Button")) {
    mUnpackNode = node2;
    mNeedUnpack = true;
    isToGetMoney = true;
    L.d("find red packet!");
    return;
   }
  }
   /* 戳開紅包,紅包已被搶完,遍歷節(jié)點匹配“已存入零錢”和“手慢了” */
  if (mLuckyMoneyPicked) {
   List<AccessibilityNodeInfo> nodes3 = this.findAccessibilityNodeInfosByTexts(this.rootNodeInfo, new String[]{
     RED_PACKET_PICKED, RED_PACKET_SAVE, RED_PACKET_PICKED2, RED_PACKET_PICKED_DETAIL});
   if (!nodes3.isEmpty()) {
    L.d("!nodes3.isEmpty()");    
    if (rootNodeInfo.getChildCount() > 1) {
     L.d("RED_PACKET_PICKED!");
    } else {
     L.d("nodes3.get(0).toString(): " + nodes3.get(0).getText().toString());
     if (!nodes3.get(0).getText().toString().equals(RED_PACKET_PICKED_DETAIL)) {
      AccessibilityNodeInfo targetNode = nodes3.get(nodes3.size() - 1);
      hongbaoInfo.getInfo(targetNode);
      if (isToGetMoney) {
       isGetMoney = true;
       isToGetMoney = false;
       gotMoney = hongbaoInfo.getMoney();
       L.d("gotMoney: " + gotMoney);
      }
      L.d("RED_PACKET_SAVE!");
      L.d("hongbaoInfo: " + hongbaoInfo.toString());
     } else {
      L.d("this packet is myself!");
     }

    }
    mNeedBack = true;
    mLuckyMoneyPicked = false;
   }
  }
 }

主要通過檢測“領(lǐng)取紅包”等關(guān)鍵文字信息來判斷是否有新紅包

檢測收到紅包時判斷是否"android.widget.LinearLayout",屏蔽聊天信息中的文字干擾

拆紅包時,由于微信版本可能不同,同時進行兩種判斷,以兼容部分版本

拆完紅包需自動返回,有以下幾種情況:搶到了,手慢了,以及該紅包是自己發(fā)出的紅包

下面是監(jiān)聽聊天列表的代碼:

private boolean watchList(AccessibilityEvent event) {
  // Not a message
  if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED || event.getSource() == null)
   return false;

  List<AccessibilityNodeInfo> nodes = event.getSource().findAccessibilityNodeInfosByText(RED_PACKET_NOTIFICATION);
  if (!nodes.isEmpty()) {
   AccessibilityNodeInfo nodeToClick = nodes.get(0);
   CharSequence contentDescription = nodeToClick.getContentDescription();
   if (contentDescription != null && !lastContentDescription.equals(contentDescription)) {
    nodeToClick.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    lastContentDescription = contentDescription.toString();
    return true;
   }
  }
  return false;
 }

下面是監(jiān)聽通知信息的代碼:

 private boolean watchNotifications(AccessibilityEvent event) {
  // Not a notification
  if (event.getEventType() != AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)
   return false;

  // Not a hongbao
  String tip = event.getText().toString();
  if (!tip.contains(RED_PACKET_NOTIFICATION)) return true;

  Parcelable parcelable = event.getParcelableData();
  if (parcelable instanceof Notification) {
   Notification notification = (Notification) parcelable;
   try {
    notification.contentIntent.send();
   } catch (PendingIntent.CanceledException e) {
    e.printStackTrace();
   }
  }
  return true;
 }

紅包信息的獲取,及日志的存儲

通過獲取節(jié)點的子信息,分別獲得紅包發(fā)送者及搶到的金額、搶紅包時間等信息,建立簡單的表單分別記錄該信息。

@Table(name = "HongbaoInfos")
public class HongbaoInfo extends Model {

 private int month;
 private int day;
 private int hour;
 private int min;
 private int sec;

 @Column(name = "sender")
 public String sender;

 @Column(name = "money")
 public String money;

 @Column(name = "time")
 public String time;

 public void getInfo(AccessibilityNodeInfo node) {

  AccessibilityNodeInfo hongbaoNode = node.getParent();
  sender = hongbaoNode.getChild(0).getText().toString();
  money = hongbaoNode.getChild(2).getText().toString();
  time = getStringTime();
 }

 private String getStringTime() {
  Calendar c = Calendar.getInstance();
  month = c.get(Calendar.MONTH) + 1;
  day = c.get(Calendar.DAY_OF_MONTH);
  hour = c.get(Calendar.HOUR_OF_DAY);
  min = c.get(Calendar.MINUTE);
  sec = c.get(Calendar.SECOND);
  return month+"月"+day+"日 "+hour+":"+min+":"+sec;
 }

 @Override
 public String toString() {
  return "HongbaoInfo [sender=" + sender + ", money=" + money + ", time=" + time + "]";
 }

 public static List<HongbaoInfo> getAll() {
  return new Select()
    .from(HongbaoInfo.class)
    .orderBy("Id ASC")
    .execute();
 }

 public static void deleteALL() {
  new Delete().from(HongbaoInfo.class).execute();
 }

 public float getMoney() {
  return Float.parseFloat(money);
 }

 public String getSender() {
  return sender;
 }

 public String getTime() {
  return time;
 }
}

存儲操作:

 private void saveToLog(HongbaoInfo hongbaoInfo) {
  if (watchedFlags.get("pref_etc_log")) {
   HongbaoInfo hongbaoInfo1 = new HongbaoInfo();
   hongbaoInfo1 = hongbaoInfo;
   hongbaoInfo1.save();
  } else {
   L.d("log closed!");
  }
 }

總結(jié)

主要的代碼到這里基本結(jié)束,目前在微信最新版上測試ok,尚還存在以下幾個問題:

    1.同一個人連續(xù)發(fā)的不能自動搶,因為為了防止重復(fù)點擊做了過濾,同一個人的紅包搶了后不會再次點擊

    2.AccessibilityService開啟時間長后有時會被系統(tǒng)關(guān)掉

結(jié)束語

以上就是本文的全部內(nèi)容了,希望對大家的學(xué)習(xí)和工作能有所幫助。

相關(guān)文章

  • Android通過SOCKET下載文件的方法

    Android通過SOCKET下載文件的方法

    這篇文章主要介紹了Android通過SOCKET下載文件的方法,實例分析了Android使用Socket進行文件傳輸?shù)募记?需要的朋友可以參考下
    2015-12-12
  • Android 對話框(Dialog)大全詳解及示例代碼

    Android 對話框(Dialog)大全詳解及示例代碼

    本文主要介紹Android 對話框的知識,這里整理了詳細資料及實現(xiàn)示例代碼及實現(xiàn)效果圖,有興趣的小伙伴可以參考下
    2016-09-09
  • Android跨進程傳遞大數(shù)據(jù)的方法實現(xiàn)

    Android跨進程傳遞大數(shù)據(jù)的方法實現(xiàn)

    這篇文章主要介紹了Android跨進程傳遞大數(shù)據(jù)的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Android本地實現(xiàn)搜索歷史記錄

    Android本地實現(xiàn)搜索歷史記錄

    這篇文章主要為大家詳細介紹了Android本地實現(xiàn)搜索歷史記錄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • Android中HttpURLConnection類使用介紹

    Android中HttpURLConnection類使用介紹

    早些時候其實我們都習(xí)慣性使用HttpClient,但是后來Android6.0之后不再支持HttpClient,需要添加Apache的jar才行,所以,就有很多開發(fā)者放棄使用HttpClient了,HttpURLConnection畢竟是標準Java接口(java.net) ,適配性還是很強的
    2022-12-12
  • Android仿京東快報無限輪播效果

    Android仿京東快報無限輪播效果

    這篇文章主要為大家詳細介紹了Android仿京東快報無限輪播效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Android實現(xiàn)界面左右滑動切換功能

    Android實現(xiàn)界面左右滑動切換功能

    相信大家一定都使用過手機QQ和微信之類的軟件,當我們使用時不難發(fā)現(xiàn)其界面的切換不僅可以通過點擊頁標簽來實現(xiàn),還可以通過左右滑動來實現(xiàn)的,下面小編給大家介紹下如何實現(xiàn)這個功能
    2016-12-12
  • flutter編寫精美的登錄頁面

    flutter編寫精美的登錄頁面

    這篇文章主要為大家詳細介紹了flutter編寫精美的登錄頁面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Android 使用Zbar實現(xiàn)掃一掃功能

    Android 使用Zbar實現(xiàn)掃一掃功能

    這篇文章主要介紹了Android 使用Zbar實現(xiàn)掃一掃功能,本文用的是Zbar實現(xiàn)掃一掃,因為根據(jù)本人對兩個庫的使用比較,發(fā)現(xiàn)Zbar解碼比Zxing速度要快,實現(xiàn)方式也簡單,需要的朋友可以參考下
    2023-03-03
  • 詳解Android微信登錄與分享

    詳解Android微信登錄與分享

    本篇文章主要對Android微信登錄與分享功能的實現(xiàn)進行了介紹。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-01-01

最新評論