An analysis of the principle of the Android steal Red envelope plug-in _android

Source: Internet
Author: User
Tags gettext int size

Rob Red envelopes, first look at the effect chart ~

To achieve automatic red envelopes, solve the problem has two points:

One: How to monitor the occurrence of red envelopes in real time

Second: How to automatically enter the page when the red envelope arrives and automatically click on the red envelope

How to obtain the event of the arrival of red envelopes

In order to get the red envelope arrival status bar changes, we need to use a class: accessibility

Many Android users have a variety of situations that cause them to interact with their phones in different ways.
This includes users whose eyesight, physical, and age problems cause them to not be able to see the full screen or to use touch screens, and also include users who are less able to receive voice information and hints.
Android offers accessibility features and services to help these users more simply manipulate devices, including text-to-speech (this does not support Chinese), tactile feedback, gesture manipulation, trackball and handle manipulation.

OK, to understand this, then the next smooth point, first look at the use of accessibility and accessibilityservice
1. Create a new class to inherit Accessibilityservice and register it in the Androidmanifest file:

 <uses-permission android:name= "Android.permission.BIND_ACCESSIBILITY_SERVICE"/> 
<application> 
<service  android:name= "Com.zkhb.weixinqinghongbao.service.QiangHongBaoService"    
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/qianghongbao_service_config "/>
   </service>
</application>

Several important overloaded methods are implemented in subclass Qianghongbaoservice:

onserviceconnected ()-optional. the system will call this method when it is successfully connected to your service, in which you can do initialization work, such as sound vibration management of the device, or call Setserviceinfo () for configuration work.
onaccessibilityevent ()-Must. through this function can receive the system sends the Accessibilityevent, receives the accessibilityevent is filtered, the filtering is when configures the work to set.

Oninterrupt ()-Must. This is invoked when the system wants to interrupt a accessibilityservice return response. are called multiple times throughout the life cycle.
Onunbind ()-optional. This accessibilityservice will be invoked when the system is going to close. Do some of the work of releasing resources in this method.

And then in/res/xml/accessibility_service_config.xml:

<accessibility-service xmlns:android= "Http://schemas.android.com/apk/res/android" Android: Accessibilityeventtypes= "Typenotificationstatechanged|typewindowstatechanged|typewindowcontentchanged"
  Android:accessibilityfeedbacktype= "Feedbackgeneric"
  android:accessibilityflags= ""
  android: Canretrievewindowcontent= "true"
  android:description= "@string/accessibility_description"
  android: notificationtimeout= "android:packagenames=" "
  com.tencent.mm"/>

Second, the main focus and how to automatically enter the page when the red envelope arrives and automatically click on the red envelope.

The changes in the status bar are monitored in the Onaccessibilityevent method, mainly:

Accessibilityevent.type_notification_state_changed,

Accessibilityevent.type_window_state_changed,

Accessibilityevent.type_window_content_changed

Handle the relevant logic when responding to a change in the form and the contents of the form, obtaining the following code to open the message with a micro-mail message:

 The notification bar message of the micro-letter is opened
    Notification Notification = (Notification) event.getparcelabledata ();
    Pendingintent pendingintent = notification.contentintent;
    try {
      pendingintent.send ();
    } catch (Pendingintent.canceledexception e) {
      e.printstacktrace ();
    }

There are a lot of specific code online, generally through: Findaccessibilitynodeinfosbytext, findaccessibilitynodeinfosbyviewid find text or resource node to click on the operation, But the new version of the micro-letter opened the Red Envelope page has been processed, without textual information, and if adopted:

This can happen with Resouces-id in this form:

After understanding the whole core, get the event is simply through the text and ID to judge, then you can change the text to the icon, the ID changed to dynamic ID (each display is randomly generated), so you can improve the threshold of the plug-in.

How to avoid it, at present, I think that since the opening of the Red Envelope page text and ID are likely to change, then we can find a constant to judge it, after considering, I think the most likely to be the same place is to open the red envelope this button position, that is, the bounds in the picture, So after thinking, I have the following processing:

 for (int i = 0; i < Nodeinfo.getchildcount (); i++) {//LOG.E ("TAG", "Getviewidresource
      Name: "+nodeinfo.getchild (i). Getviewidresourcename ());
      Rect outbounds = new Rect ();
      Nodeinfo.getchild (i). Getboundsinscreen (Outbounds);
      int LEFT_DP = Px2dip (this, 400);
      int TOP_DP = Px2dip (this, 1035);
      int RIGHT_DP = Px2dip (this, 682);

      int BOTTOM_DP = Px2dip (this, 1320);
      int left_px = dip2px (this, LEFT_DP);
      int top_px = dip2px (this, TOP_DP);
      int right_px = dip2px (this, RIGHT_DP);

      int bottom_px = dip2px (this, BOTTOM_DP);
      Rect Mstandar = new Rect (LEFT_PX,TOP_PX,RIGHT_PX,BOTTOM_PX); if (Mstandar.contains (outbounds)) {LOG.E ("TAG", "Outbounds.left: +outbounds.left+"; Outbounds.top: "+outbounds.top+
        Outbounds.right: "+outbounds.right+"; Outbounds.bottom: "+outbounds.bottom";
        Nodeinfo.getchild (i). Performaction (Accessibilitynodeinfo.action_click);
      Break }
    }

The rectangular area taken here is slightly larger than the button area, and then determine whether the Red Envelopes page button is in our pre-set area, if in, we directly to open the red envelope operation: Accessibilitynodeinfo.action_click.
Other details, such as how to prevent repeated robbery, are also issues to be addressed.
OK, just drop the key code for reference only:

Package com.zkhb.weixinqinghongbao.service;
Import Java.util.Date;

Import java.util.List;
Import Android.accessibilityservice.AccessibilityService;
Import Android.annotation.SuppressLint;
Import Android.annotation.TargetApi;
Import Android.app.KeyguardManager;
Import Android.app.KeyguardManager.KeyguardLock;
Import android.app.Notification;
Import Android.app.NotificationManager;
Import android.app.PendingIntent;
Import Android.content.Context;
Import android.content.Intent;
Import Android.graphics.Rect;
Import Android.os.Build;
Import Android.os.Handler;
Import Android.os.PowerManager;
Import Android.os.PowerManager.WakeLock;
Import Android.util.Log;
Import android.view.accessibility.AccessibilityEvent;
Import Android.view.accessibility.AccessibilityManager;
Import Android.view.accessibility.AccessibilityNodeInfo;

Import Android.widget.Toast;
Import com.zkhb.weixinqinghongbao.MainActivity;
Import COM.ZKHB.WEIXINQINGHONGBAO.R;
Import Com.zkhb.weixinqinghongbao.entity.HongBaoInfo; IMport Com.zkhb.weixinqinghongbao.util.DateFormatUtils;

Import Com.zkhb.weixinqinghongbao.util.LogUtil; /** * * Rob Red Envelopes Service/@SuppressLint ("Newapi") public class Qianghongbaoservice extends Accessibilityservice {//static F

  inal String TAG = "Qianghongbao";
  /** Micro-Letter package name/static final String wechat_packagename = "com.tencent.mm";
  /** RED Envelope Message keyword * * static final String Hongbao_text_key = "[Micro-letter red envelopes]";

  /** RED Envelope Message keyword * * static final String hongbao_text_key1 = "micro-letter Red envelopes";

  private static final int envelope_return = 0;

  private static final String Lock_tag = "screen";
  Handler Handler = new Handler ();
  /** whether in the grab Red envelopes Interface * *//public boolean isinmm=false;
  /** whether you can click//public boolean isclicked=false;
  Whether the/** has entered the "Red envelope" interface * * public static Boolean iscominqiangchb=false;
  True public static Boolean iscominqiangchb2=false;
   True judgment public static Boolean iscominqiangchb3=false;

  /** whether from the notification bar * * private static Boolean iscomnotify=false;
  Private PowerManager pm; Light Screen Private WakeloCK Mwakelock;
  Unlock the lock screen private keyguardlock keyguardlock;
  /** to determine whether the user before the lock screen * * private static Boolean islock=false;
  /** Notice Service * * Private Notificationmanager N_manager; public void Unlock () {if (pm==null) {pm = (PowerManager) getapplication (). Getsystemservice (Context.power_service)
    ;
    Boolean Isscreenon = Pm.isscreenon ();//If true, the screen is "lit", otherwise the screen is "dimmed".
      if (!isscreenon) {islock=true;
      Keyguardmanager Keyguardmanager = (keyguardmanager) getsystemservice (Keyguard_service);
      Keyguardlock = Keyguardmanager.newkeyguardlock (Lock_tag);

      Keyguardlock.disablekeyguard (); Mwakelock = Pm.newwakelock (Powermanager.full_wake_lock | 
      Powermanager.acquire_causes_wakeup, Lock_tag);
    Mwakelock.acquire ();
      } public void Lock () {if (Islock) {//Release screen illuminated steady lock if (null!= mwakelock) {mwakelock.release ();
      }//Screen lock if (keyguardlock!=null) {keyguardlock.reenablekeyguard ();
  }}} @Overridepublic void Onaccessibilityevent (Accessibilityevent event) {final int eventtype = Event.geteventtype ();

    Logutil.info ("Events---->" + event);
      Notification Bar Event if (EventType = = accessibilityevent.type_notification_state_changed) {unlock ();
      list<charsequence> texts = Event.gettext ();
          if (!texts.isempty ()) {for (charsequence t:texts) {String text = string.valueof (t);
            if (Text.contains (Hongbao_text_key)) {iscomnotify=true;
            Iscominqiangchb=false;
            Opennotify (event);
          Break
      else if (EventType = accessibilityevent.type_window_state_changed) {unlock ();
Openhongbao (event);
Accessibilitynodeinfo nodeinfo = Getrootinactivewindow (); list<accessibilitynodeinfo> Findaccessibilitynodeinfosbytext = Nodeinfo.findaccessibilitynodeinfosbytext (
"To receive red envelopes"); if (Findaccessibilitynodeinfosbytext.isempty ()) {//Isinmm=false;
}else{//Isinmm=true;//}//List<charsequence> text = Event.gettext (); if (Text.size () >=0) {//Charsequence charsequence = text.get (0);////if (Charsequence.equals ("micro-letter") {////isinmm=true;////}else{////isinmm=false;////}//}}else if (EventType
      ==accessibilityevent.type_window_content_changed && iscomnotify) {unlock ();
      Openhongbao (event);
      list<accessibilitynodeinfo> InfoText = Getrootinactivewindow (). Findaccessibilitynodeinfosbytext ("Receive red envelopes"); if (!
        Infotext.isempty ()) {CheckKey2 ();
      Iscomnotify=false;
    }}/* @Override protected Boolean onkeyevent (KeyEvent event) {//return super.onkeyevent (event);
  return true; 
    }*/@Override Public boolean onunbind (Intent Intent) {Toast.maketext (this, "disconnect the red Envelope service", Toast.length_short). Show ();
    Iscominqiangchb=false;
    Islock=false;
    Iscominqiangchb2=false;Iscominqiangchb3=false;
    Iscomnotify=false;
    Setnotification ("has closed Rob Red Envelope Small assistant service ~ ~", Notification.flag_auto_cancel, "has closed to rob Red Envelopes Small Assistant Service ~ ~ ~)");
  return Super.onunbind (Intent);
  @Override public void Oninterrupt () {Toast.maketext (this, "break the red Envelope service", Toast.length_short). Show ();
    } @Override protected void onserviceconnected () {super.onserviceconnected ();
    Iscominqiangchb=false;
    Iscominqiangchb2=false;
    Iscominqiangchb3=false;
    Islock=false;

    Iscomnotify=false;

    Setnotification ("has opened to rob Red Envelopes Small assistant Service ~ ~", Notification.flag_no_clear, "has opened to rob Red Envelopes Small Assistant Service ~ ~ ~]");
  Toast.maketext (This, "link to rob Red Envelopes Service", Toast.length_short). Show (); } private void Setnotification (String content,int flags,string title) {if (n_manager==null) {N_manager = (not
    Ificationmanager) Getapplicationcontext (). Getsystemservice (Context.notification_service);
    } n_manager.cancelall ();
Notification notification=new Notification (r.drawable.ic_launcher, Content, System.currenttimemillis ());    //Notification.defaults |= notification.default_vibrate; Long[] vibrate = {0,100,200,300};
    0 milliseconds after the vibration, vibration 100 milliseconds after the stop, after 200 milliseconds again vibration 300 milliseconds//notification.vibrate=vibrate; Notification.flags |= flags; Indicates that the notice is not cleared after clicking the "purge notice" in the notification bar, Intent notificationintent = new Intent (this,mainactivity.class); Click on the notification to jump to the activity pendingintent contentintent = pendingintent.getactivity (Getapplicationcontext (), 0,
    notificationintent,0);

    Notification.setlatesteventinfo (Getapplicationcontext (), title, "into the micro-letter to rob Red envelopes ~ ~", contentintent);
  N_manager.notify (0, notification); private void Sendnotifyevent () {Accessibilitymanager manager= (accessibilitymanager) Getsystemservice (ACCESSIBILIT
    Y_service);
    if (!manager.isenabled ()) {return;
    } accessibilityevent Event=accessibilityevent.obtain (accessibilityevent.type_notification_state_changed);
    Event.setpackagename (Wechat_packagename);
    Event.setclassname (Notification.class.getName ()); Charsequence Tickertext = theBao_text_key;
    Event.gettext (). Add (Tickertext);
  Manager.sendaccessibilityevent (event); /** Open the Notification bar message/@TargetApi (build.version_codes. Jelly_bean) private void Opennotify (Accessibilityevent event) {if (event.getparcelabledata () = NULL | |! (
    Event.getparcelabledata () instanceof Notification)) {return;
    ///Turn the message of the micro-letter into Notification Notification = (Notification) event.getparcelabledata ();
    Pendingintent pendingintent = notification.contentintent;
    try {pendingintent.send ();
    catch (Pendingintent.canceledexception e) {e.printstacktrace (); }} @TargetApi (Build.version_codes. Jelly_bean) private void Openhongbao (Accessibilityevent event) {if ("Com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyR
      Eceiveui ". Equals (Event.getclassname ())) {//point in the red envelopes, the next step is to remove the red envelope iscominqiangchb=true;
      Iscominqiangchb2=true;
    CheckKey1 (); else if ("Com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI". Equals (EVENT.GETCLAssname ()) {//Logutil.info the detailed record interface after the red envelope ("event---->com.tencent.mm.plugin.luckymoney.ui.luckymoneydetailui")
       ); Nonething//if (ISCOMINQIANGCHB) {//Iscominqiangchb=false;//} if (ISCOMINQIANGCHB2) {ISC
       Ominqiangchb3=true;
       }else{Iscominqiangchb3=false;
      } CheckKey3 ();
      Iscominqiangchb=true;
      Iscominqiangchb2=false;
      Performglobalaction (Accessibilityservice.global_action_back); if (getsharedpreferences ("config", context.mode_private). Getboolean ("Auto", False)) {Performglobalaction (Accessibi
      Lityservice.global_action_home);
    Lock ();
      else if ("Com.tencent.mm.ui.LauncherUI". Equals (Event.getclassname ())) {//isinmm=true;
      In the chat interface, go to the point of the red envelope logutil.info ("event---->com.tencent.mm.ui.launcherui");
    CheckKey2 (); }} @SuppressLint ("Newapi") @TargetApi (build.version_codes. Jelly_bean) private void CheckKey3 () {Accessibilitynodeinfo NodeInfo =Getrootinactivewindow ();
       if (NodeInfo = = null) {Logutil.info ("Rootwindow is empty 333");
     Return }//todo list<accessibilitynodeinfo> Findaccessibilitynodeinfosbytext = Nodeinfo.findaccessibilitynodeinfo
     Sbytext ("Yuan"); if (Findaccessibilitynodeinfosbytext.size () >=0) {Accessibilitynodeinfo AccessibilityNodeInfo2 = Findaccessibilit
       Ynodeinfosbytext.get (0). GetParent ();
       Charsequence money = Accessibilitynodeinfo2.getchild (2). GetText ();
       Charsequence name = Accessibilitynodeinfo2.getchild (0). GetText ();
         if (ISCOMINQIANGCHB3) {hongbaoinfo info=new hongbaoinfo ();
         Info.setstrdatetime (Dateformatutils.format ("Yyyy-mm-dd HH:mm:ss", New Date ());
         Info.setstrmoney (money+ "");
         Info.setstrname (name+ "");
       Info.save ();
     } toast.maketext (Getapplicationcontext (), money+ ":::" +name, 0). Show (); }//List<accessibilitynodeinfo> Findaccessibilitynodeinfosbyviewid = Nodeinfo.findacCessibilitynodeinfosbyviewid ("Com.tencent.mm:id/aw8");
Accessibilitynodeinfo accessibilitynodeinfo = findaccessibilitynodeinfosbyviewid.get (0); 
  Charsequence text = Accessibilitynodeinfo.gettext ();
    private void CheckKey1 () {Accessibilitynodeinfo nodeinfo = Getrootinactivewindow ();
      if (NodeInfo = = null) {Logutil.info ("Rootwindow is empty 11111");
    Return for (int i = 0; i < Nodeinfo.getchildcount (); i++) {LOG.E ("TAG", "Getviewidresourcename:" +nodeinfo.getch
      ILD (i). Getviewidresourcename ());
      Rect outbounds = new Rect ();
      Nodeinfo.getchild (i). Getboundsinscreen (Outbounds);
      int LEFT_DP = Px2dip (this, 400);
      int TOP_DP = Px2dip (this, 1035);
      int RIGHT_DP = Px2dip (this, 682);

      int BOTTOM_DP = Px2dip (this, 1320);
      int left_px = dip2px (this, LEFT_DP);
      int top_px = dip2px (this, TOP_DP);
      int right_px = dip2px (this, RIGHT_DP);

      int bottom_px = dip2px (this, BOTTOM_DP); Rect Mstandar = nEW Rect (LEFT_PX,TOP_PX,RIGHT_PX,BOTTOM_PX); if (Mstandar.contains (outbounds)) {LOG.E ("TAG", "Outbounds.left: +outbounds.left+"; Outbounds.top: "+outbounds.top+
        Outbounds.right: "+outbounds.right+"; Outbounds.bottom: "+outbounds.bottom";
        Nodeinfo.getchild (i). Performaction (Accessibilitynodeinfo.action_click);
      Break }//Nodeinfo.performaction (Action)//[405,1042][675,1312]}//list<accessibilitynodeinfo> List = nodeInf

O.findaccessibilitynodeinfosbytext ("Remove red envelopes");
list<accessibilitynodeinfo> list = Nodeinfo.findaccessibilitynodeinfosbyviewid ("com.tencent.mm:id/b5d"); for (Accessibilitynodeinfo n:list) {//N.performaction (Accessibilitynodeinfo.action_click);//}} PR
    ivate void CheckKey2 () {Accessibilitynodeinfo nodeinfo = Getrootinactivewindow ();
      if (NodeInfo = = null) {Logutil.info ("Rootwindow is empty 222222");
    Return } list<accessibilitynodeinfo> List = nodeinfo.findaccessibilityNodeinfosbytext ("Collect red envelopes");
      if (List.isEmpty ()) {list = Nodeinfo.findaccessibilitynodeinfosbytext (Hongbao_text_key);
        for (Accessibilitynodeinfo n:list) {logutil.info ("--> micro Red Envelope:" + N);
        N.performaction (Accessibilitynodeinfo.action_click);
      Break } else {//The latest red envelopes lead Accessibilitynodeinfo parent = List.get (List.size ()-1). GetParent ();//LOG.W (TA G, "isclicked::" +isclicked)!
      isclicked; if (parent!= null &&!)
      ISCOMINQIANGCHB) {parent.performaction (Accessibilitynodeinfo.action_click); }//for (int i = List.size ()-1; I >= 0; I-) {//Accessibilitynodeinfo parent = List.get (i). GetParent ()
;
LOG.I (TAG, "--> Collect Red Envelopes:" + parent); if (parent!= null && parent.isclickable ()) {//Parent.performaction (accessibilitynodeinfo.acti
On_click);
Break
    }//}//Performglobalaction (Accessibilityservice.global_action_back);
 } /** * @param info Current node * @param matchflag need to match text * @param type of Operation * * @SuppressLint ("Newapi") pub LIC void Recycle (accessibilitynodeinfo info, String matchflag, int type) {if (info!= null) {if (info.getchild
        Count () = = 0) {charsequence desrc = info.getcontentdescription (); Switch (type) {case envelope_return://returns if (desrc!= null && matchflag.equals (info.getcont Entdescription (). toString (). Trim ()) {if (info.ischeckable ()) {info.performaction Accessib
              Ilitynodeinfo.action_click);
              else {performglobalaction (accessibilityservice.global_action_back);
        }} break;
        } else {int size = Info.getchildcount ();
          for (int i = 0; i < size; i++) {Accessibilitynodeinfo ChildInfo = Info.getchild (i); if (ChildInfo!= null) {Logutil.info ("index: + i +")Info "+ childinfo.getclassname () +": "+ childinfo.getcontentdescription () +": "+info.gettext ());
          Recycle (ChildInfo, Matchflag, type);
    @Override public void OnDestroy ()}}}} {Super.ondestroy ();
  Lock ();  /** * According to the resolution of the mobile phone from the dip unit to become PX (pixel)/public static int dip2px (context, float Dpvalue) {final 
    Float scale = context.getresources (). Getdisplaymetrics (). density; 
  return (int) (Dpvalue * scale + 0.5f); /** * change from PX (pixel) unit to DP/public static int PX2DIP based on cell resolution (context, float pxvalue) {//fi 
    nal Float scale = context.getresources (). Getdisplaymetrics (). density; return (int) (PXVALUE/3 + 0.5f);
 3 is my mobile phone's device density}

Accessibilityservice can also be used in intelligent installation, virtual buttons have a lot of applications, such practice is only to give us a solution to the problem of another kind of thinking, the problem is always to be solved.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.