使用monkeyrunner实现手机自动转账功能

背景,大概就是需要用手机给同一帐号转账几百笔,手动太麻烦,就写个自动化程序去完成。
关键技术是monkeyrunner,难点是手机验证码的自动化输入。

monkeyrunner是谷歌官方提供的,可以模拟手机点击的自动化测试工具,可以录制用户的点击坐标,具体可以参考:
http://blog.csdn.net/mad1989/article/details/38087737

同时monkeyrunner 需要用到python语言,python语言入门可以参考:
http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html
python官方的文档:
http://www.kuqin.com/abyteofpython_cn/index.html
初步感觉python的设计观点是力求让程序语言的代码简单,将更多的工作交给解释器来执行,变量不用声明以及指定类型,函数不用指定类型,变量都是对内存中的常量的引用。

回到正题,要实现这个功能需要三个部分。一、手机需要一个监听软件,将监听到的短信的验证信息读出,并放到一个电脑能访问的地方(sdcard)。二、执行python,python需要一个脚本文件用来控制输入。三、手机和电脑交互的桥梁管理软件,负责将手机上的验证码pull到电脑上面,并更新到脚本中去。

手机端需要监听短信
需要权限,包含读写sdcard文件:

    <uses-permission android:name="android.permission.RECEIVE_SMS" >
    </uses-permission>
    <uses-permission android:name="android.permission.READ_SMS" >
    </uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

设置监听:

public class SmsReceier extends BroadcastReceiver {

    public static final String TAG = "ImiChatSMSReceiver";
    public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(SMS_RECEIVED_ACTION)) {
            SmsMessage[] messages = getMessagesFromIntent(intent);
            for (SmsMessage message : messages) {
                Log.v(TAG, message.getOriginatingAddress() + " : " +
                        message.getDisplayOriginatingAddress() + " : " +
                        message.getDisplayMessageBody() + " : " +
                        message.getTimestampMillis());
                String mesBody = message.getDisplayMessageBody().substring(11,17);  //这几位为短信验证码
                File file = new File("/sdcard/number.txt");
                try {
                    FileWriter fileWriter = new FileWriter(file);
                    fileWriter.write(mesBody);
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

电脑端的程序参照上面分享的monkeyrunner的教程。

最后管理软件,首先将sdcard包含的验证码的文件pull到电脑上面,因为服务器发给手机的短信的时间是不确定的,所以需要监测该文件是否是新短信的信息,验证码前后两天一般不同,利用这个可以验证是否是新的短信。最后两次模拟操作的时间间隔需要留够。

package com.czfree.SCRX;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import com.sun.jndi.url.iiopname.iiopnameURLContextFactory;


public class SCRX_Main {
    public static int number_old = 0;
    public static int number_new = 0;
    public static String path = "C:\\czfree\\code\\Environ\\sdk\\tools";
    public static String numberValue[]=new String[]{     //0到9数字的坐标
        "TOUCH|{'x':624,'y':1828,'type':'downAndUp',}\n",
        "TOUCH|{'x':303,'y':1328,'type':'downAndUp',}\n",
        "TOUCH|{'x':546,'y':1288,'type':'downAndUp',}\n",
        "TOUCH|{'x':816,'y':1300,'type':'downAndUp',}\n",
        "TOUCH|{'x':300,'y':1528,'type':'downAndUp',}\n",
        "TOUCH|{'x':580,'y':1504,'type':'downAndUp',}\n",
        "TOUCH|{'x':820,'y':1512,'type':'downAndUp',}\n",
        "TOUCH|{'x':307,'y':1632,'type':'downAndUp',}\n",
        "TOUCH|{'x':526,'y':1640,'type':'downAndUp',}\n",
        "TOUCH|{'x':806,'y':1684,'type':'downAndUp',}\n"
    };
    public static String OtherValue = "TOUCH|{'x':702,'y':720,'type':'downAndUp',}\n" +    //输入验证码后面的步骤
        "WAIT|{'seconds':1.0,}\n" +
        "TOUCH|{'x':172,'y':1844,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':1.0,}\n"+
        "TOUCH|{'x':590,'y':1380,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':1.0,}\n"+
        "TOUCH|{'x':283,'y':1380,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':1.0,}\n"+
        "TOUCH|{'x':1029,'y':1380,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':1.0,}\n"+
        "TOUCH|{'x':492,'y':1372,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':1.0,}\n"+
        "TOUCH|{'x':1026,'y':1376,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':1.0,}\n"+
        "TOUCH|{'x':931,'y':1360,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':1.0,}\n"+
        "TOUCH|{'x':749,'y':1140,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':2.0,}\n"+
        "TOUCH|{'x':722,'y':1156,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':9.0,}\n"+
        "TOUCH|{'x':344,'y':1092,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':3.0,}\n"+
        "TOUCH|{'x':951,'y':388,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':4.0,}\n"+
        "TOUCH|{'x':327,'y':1424,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':3.0,}\n"+
        "TOUCH|{'x':472,'y':776,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':2.0,}\n"+
        "TOUCH|{'x':239,'y':1376,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':2.0,}\n"+
        "TOUCH|{'x':718,'y':812,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':2.0,}\n"+
        "TOUCH|{'x':492,'y':1080,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':6.0,}\n"+
        "TOUCH|{'x':634,'y':1392,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':6.0,}\n"+
        "TOUCH|{'x':513,'y':880,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':2.0,}\n"+
        "TOUCH|{'x':77,'y':1840,'type':'downAndUp',}\n"+
        "WAIT|{'seconds':1.0,}";


    public static boolean HasChange(){     //判断是否接到新的短信
        try {
            File file = new File(path + "\\number.txt");
            BufferedReader br = new BufferedReader(new FileReader(file));
            number_new = Integer.parseInt(br.readLine());
            br.close();
            if(number_new != number_old){
                number_old = number_new;
//              System.out.println(number_new+"   "+ number_old);
                return true;
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (NumberFormatException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;

    }

    public static void ChangeAction() {      //根据验证码更新脚本信息
        try {
            String wite = "WAIT|{'seconds':1.0,}\n";
            int num = 100000;
            int number_chu = number_new;
            File file = new File(path + "\\action.mr");
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));

//          String now = numberValue[0] + wite;
            for( int i = 0; i < 6 ; i++){
                bos.write("WAIT|{'seconds':0.5,}\n".getBytes());
                bos.write("WAIT|{'seconds':0.5,}\n".getBytes());
                int nownum = number_chu/num;
//              now = now + numberValue[nownum] + wite;
                bos.write(numberValue[nownum].getBytes());
                System.out.println(nownum);
                System.out.println(numberValue[nownum]);
                bos.flush();
                number_chu = number_chu%num;
                num = num/10;
            }
            bos.write("WAIT|{'seconds':1.0,}\n".getBytes());
            bos.write(OtherValue.getBytes());
            bos.flush();
            bos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        new Thread(){
            public void run() {
                while(true){
                    Process process;
                    try {
                        process = Runtime.getRuntime().exec("adb pull /sdcard/number.txt " + path + "\\number.txt");   //pull手机中的验证码信息
                        process.waitFor();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
//                  
                    if(!HasChange()){
                        System.out.println(number_new);
                        try {
                            sleep(5000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    else{
                        ChangeAction();
                        try {
                        //执行monkeyrunner操作
                            Process process1 = Runtime.getRuntime().exec(path + "\\monkeyrunner.bat "+ path + "\\monkey_playback.py " + path +"\\action.mr" ); 
                            process1.waitFor();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            };
        }.start();
    }

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值