您的位置:首页 > 移动开发 > Android开发

利用android monkey 抢支付宝红包

2015-02-27 22:23 225 查看
春节来临期间互联网大鳄们纷纷祭出红包必杀技,各种抢红包。支付宝的整点抢红包形式是一个戳人的游戏。话说这个游戏比得就是手快,由此用过
android monkey
(猴子)工具的人自然可想到抢红包绝招了吧。对,没错这就是绝迹江湖的一阳指,又名
adb monkey
.下面我就来向大家演示下我是怎么用monkey 戳中支付宝抢红包游戏的每一个小人。

注意如果支付宝有无密码交易的设置请谨慎使用,否则monkey 乱点击可能造成误交易。

两种方式

shell 工具 适用于mac linux(android 客户端)

代码:

echo 开始抓红包啦 ,good luck!
#抢红包持续的时间,单位是秒默认持续时间60秒!
tTime=60
count=$(($tTime*1000/10))
echo $count
adb shell monkey -p com.eg.android.AlipayGphone --pct-touch 100 --throttle 10 $count &

while(true)
do
read -p "停止抓红包(按任意键再回车,程序退出)" var
case "$var" in
*)
adb shell kill $(adb shell ps |awk '/monkey/{print $2}')
echo good luck
kill -9 $!
exit 0
;;
esac
done


com.eg.android.AlipayGphone
:支付宝客户客户端packageName

--pct-touch 100
触摸占比(这里100%)

throttle 10
触摸点击间隔,时间单位毫秒(这里10毫秒点击一次)

$count
触摸次数(这里由总的点击持续时间计算出)

最后一个&符号表示此命令作为一个后台命令所以不会影响后续的命令执行。

后面的while 循环实时监控终端输入停止上面的monkey 点击事件。

直接运行于android 的apk

需要手机root权限

上代码:

首先需要请求root权限执行 android 手机内部的monkey 命令(system/bin/monkey)

/*
* commonds 执行的命令
* isRoot 是否需要root 权限
*/
public static CommandResult execCommand(String command, boolean isRoot,
boolean isNeedResultMsg) {
return execCommand(new String[] { command }, isRoot, isNeedResultMsg);
}

/*
* commonds 执行的命令
* isRoot 是否需要root 权限
*/
public static CommandResult execCommand(String[] commands, boolean isRoot,
boolean isNeedResultMsg) {
int result = -1;
if (commands == null || commands.length == 0) {
return new CommandResult(result, null, null);
}

Process process = null;
BufferedReader successResult = null;
BufferedReader errorResult = null;
StringBuilder successMsg = null;
StringBuilder errorMsg = null;

DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec(
isRoot ? COMMAND_SU : COMMAND_SH);
os = new DataOutputStream(process.getOutputStream());
for (String command : commands) {
if (command == null) {
continue;
}

// donnot use os.writeBytes(commmand), avoid chinese charset
// error
os.write(command.getBytes());
os.writeBytes(COMMAND_LINE_END);
os.flush();
}
os.writeBytes(COMMAND_EXIT);
os.flush();

result = process.waitFor();
// get command result
if (isNeedResultMsg) {
successMsg = new StringBuilder();
errorMsg = new StringBuilder();
successResult = new BufferedReader(new InputStreamReader(
process.getInputStream()));
errorResult = new BufferedReader(new InputStreamReader(
process.getErrorStream()));
String s;
while ((s = successResult.readLine()) != null) {
successMsg.append(s);
}
while ((s = errorResult.readLine()) != null) {
errorMsg.append(s);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
if (successResult != null) {
successResult.close();
}
if (errorResult != null) {
errorResult.close();
}
} catch (IOException e) {
e.printStackTrace();
}

if (process != null) {
process.destroy();
}
}
return new CommandResult(result, successMsg == null ? null
: successMsg.toString(), errorMsg == null ? null
: errorMsg.toString());
}

/*
* 执行命令单独成一个服务这样避免阻塞ui线程造成无响应
*/

public class StartService extends Service {

private static String tag = "StartService";
private static boolean isStart = false;
public static int totalTime = 60;// second
public static int speed = 2;
private static int count = totalTime * 1000 / 5;

@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.e(tag, "onBind");
return null;
}

@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.e(tag, "create");
super.onCreate();
}
/*
* (non-Javadoc)
* @see android.app.Service#onStartCommand(android.content.Intent, int, int)
*
*/

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.e(tag, "onStartCommond:flags:" + flags + ",startid:" + startId
+ ";action:" + intent.getAction() + ";extra:"
+ intent.getExtras().get("start"));
start();

return super.onStartCommand(intent, flags, startId);
}

/*
* 结束点击事件
*/
public static void stopMonkey() {
isStart = false;
String commond = "kill $(ps |awk '/monkey/{print $2}')";
CommandResult result = ShellUtils.execCommand(commond, true, true);
Log.e("stop Reuslt:", "successMsg:" + result.successMsg + "errorMsg:"
+ result.errorMsg + "result:" + result.result);
}
/*
* 启动服务
*/
public static void start() {
if (isStart) {
return;
}
isStart = true;
String commond = "monkey -p com.eg.android.AlipayGphone --pct-touch 100 --throttle "
+ speed + " " + count + "& >&/dev/null";
CommandResult result = ShellUtils.execCommand(commond, true, true);
Log.e("start Reuslt:", "successMsg:" + result.successMsg + "errorMsg:"
+ result.errorMsg + "result:" + result.result);
}
}

/*
* activity 可配置抢红包持续时间以及速度
*/

public class MainActivity extends ActionBarActivity {

private CastReceive receiver;
private static String tag = "MainActivity";
private Notification notifi;
private NotificationManager nm;

@Override
protected void onCreate(Bundle savedInstanceState) {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
registReceive();
}

private void initViews() {

Button btn = (Button) findViewById(R.id.done);
btn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
createNotifaction();

EditText speed = (EditText) findViewById(R.id.speed);
String speedStr = speed.getEditableText().toString();
int speedInteger = Integer.valueOf(speedStr);
if (speedInteger != 0) {
StartService.speed = 5 / speedInteger;
}

EditText total = (EditText) findViewById(R.id.total);

int totalInteger = Integer.valueOf(total.getEditableText()
.toString());

if (totalInteger != 0) {
StartService.totalTime = totalInteger;

}

}
});
Button start = (Button) findViewById(R.id.start);
start.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
StartService.start();
}
});

}

private void registReceive() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
receiver = new CastReceive();
registerReceiver(receiver, filter);
}

private void unRegistReceiver() {
if (receiver != null) {
this.unregisterReceiver(receiver);
}
}
/**
* 创建通知
*/
private void createNotifaction() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
this);
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
builder.setAutoCancel(false);
builder.setOngoing(true);

notifi = builder.build();
Intent intent = new Intent();
intent.setClass(getApplicationContext(), StartService.class);
intent.putExtra("start", "hehe");
PendingIntent pendingIntent = PendingIntent.getService(
this.getApplicationContext(), 0, intent, 0);
notifi.when = System.currentTimeMillis();
notifi.icon = R.drawable.ic_launcher;
notifi.tickerText = "asdfsda";
RemoteViews remote = new RemoteViews(getPackageName(), R.layout.remote);
remote.setOnClickPendingIntent(R.id.iambtn, pendingIntent);
notifi.contentView = remote;
Log.e(tag, "createNOtofiy");
nm.notify(R.string.app_name, notifi);
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//移除通知,结束监听服务
nm.cancelAll();
try {
unRegistReceiver();
Intent intent = new Intent();
intent.setClass(getApplicationContext(), StartService.class);
stopService(intent);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}


完整代码就不贴了,如有需要请留言。

此案例可延伸为更丰富的压力测试,通过配置adb monkey 其他的参数。

关于android monkey 更多地使用自行脑补了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android adb shell