Android随笔之——用shell脚本模拟用户按键、触摸操作
2014-11-19 14:33
363 查看
之前写过两篇关于Android中模拟用户操作的博客(其实用一篇是转载的),现在就来讲讲用shell脚本来模拟用户按键操作。本次的目标是用shell脚本打开微信并在其搜索框中搜索相关内容。
本文的模拟功能主要是用adb的input命令来实现,如果你adb的环境变量配置正确的话,在cmd中输入 adb shell input 就可以看见input的用法了。
下面直接上安卓用户操作的代码,就一个MainActivity而已,UI、Mainfest都不用配置(可能需要root权限)
效果图:
View Code
作者:登天路
转载请说明出处:http://www.cnblogs.com/travellife/
本文的模拟功能主要是用adb的input命令来实现,如果你adb的环境变量配置正确的话,在cmd中输入 adb shell input 就可以看见input的用法了。
usage: input ... input text //输入文字(中文不支持) input keyevent //keyevent按键 input [touchscreen|touchpad|touchnavigation] tap <x> <y>//点击屏幕 input [touchscreen|touchpad|touchnavigation] swipe <x1> <y1> <x2> <y2> //屏幕滑动 input trackball press //滚球已经不用了 input trackball roll //滚球已经不用了 input rotationevent 0 1->90 2->180 3->270> //顺时针旋转
下面直接上安卓用户操作的代码,就一个MainActivity而已,UI、Mainfest都不用配置(可能需要root权限)
package com.lsj.adb; import java.io.DataOutputStream; import android.app.Activity; import android.os.Bundle; import android.view.Menu; public class MainActivity extends Activity { private String[] search = { "input keyevent 3",// 返回到主界面,数值与按键的对应关系可查阅KeyEvent "sleep 1",// 等待1秒 "am start -n com.tencent.mm/com.tencent.mm.ui.LauncherUI",// 打开微信的启动界面,am命令的用法可自行百度、Google "sleep 3",// 等待3秒 "am start -n com.tencent.mm/com.tencent.mm.plugin.search.ui.SearchUI",// 打开微信的搜索 "input text 123",// 像搜索框中输入123,但是input不支持中文,蛋疼,而且这边没做输入法处理,默认会自动弹出输入法 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //如果input text中有中文,可以将中文转成unicode进行input,没有测试,只是觉得这个思路是可行的 search[5] = chineseToUnicode(search[5]); execShell(search); } /** * 执行Shell命令 * * @param commands * 要执行的命令数组 */ public void execShell(String[] commands) { // 获取Runtime对象 Runtime runtime = Runtime.getRuntime(); DataOutputStream os = null; try { // 获取root权限,这里大量申请root权限会导致应用卡死,可以把Runtime和Process放在Application中初始化 Process process = runtime.exec("su"); 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("\n"); os.flush(); } os.writeBytes("exit\n"); os.flush(); process.waitFor(); } catch (Exception e) { e.printStackTrace(); } } /** * 把中文转成Unicode码 * @param str * @return */ public String chineseToUnicode(String str){ String result=""; for (int i = 0; i < str.length(); i++){ int chr1 = (char) str.charAt(i); if(chr1>=19968&&chr1<=171941){//汉字范围 \u4e00-\u9fa5 (中文) result+="\\u" + Integer.toHexString(chr1); }else{ result+=str.charAt(i); } } return result; } /** * 判断是否为中文字符 * @param c * @return */ public boolean isChinese(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { return true; } return false; } }
效果图:
/** * 类名 RootContext.java 说明 获取root权限 创建日期 2012-8-21 作者 LiWenLong Email * lendylongli@gmail.com 更新时间 $Date$ 最后更新者 $Author$ */ public class RootContext { private static RootContext instance = null; private static Object mLock = new Object(); String mShell; OutputStream o; Process p; private RootContext(String cmd) throws Exception { this.mShell = cmd; init(); } public static RootContext getInstance() { if (instance != null) { return instance; } synchronized (mLock) { try { instance = new RootContext("su"); } catch (Exception e) { while (true) try { instance = new RootContext("/system/xbin/su"); } catch (Exception e2) { try { instance = new RootContext("/system/bin/su"); } catch (Exception e3) { e3.printStackTrace(); } } } return instance; } } private void init() throws Exception { if ((this.p != null) && (this.o != null)) { this.o.flush(); this.o.close(); this.p.destroy(); } this.p = Runtime.getRuntime().exec(this.mShell); this.o = this.p.getOutputStream(); system("LD_LIBRARY_PATH=/vendor/lib:/system/lib "); } private void system(String cmd) { try { this.o.write((cmd + "\n").getBytes("ASCII")); return; } catch (Exception e) { while (true) try { init(); } catch (Exception e1) { e1.printStackTrace(); } } } public void runCommand(String cmd) { system(cmd); } /** * 判断是否已经root了 * */ public static boolean hasRootAccess(Context ctx) { final StringBuilder res = new StringBuilder(); try { if (runCommandAsRoot(ctx, "exit 0", res) == 0) return true; } catch (Exception e) { } return false; } /** * 以root的权限运行命令 * */ public static int runCommandAsRoot(Context ctx, String script, StringBuilder res) { final File file = new File(ctx.getCacheDir(), "secopt.sh"); final ScriptRunner runner = new ScriptRunner(file, script, res); runner.start(); try { runner.join(40000); if (runner.isAlive()) { runner.interrupt(); runner.join(150); runner.destroy(); runner.join(50); } } catch (InterruptedException ex) { } return runner.exitcode; } private static final class ScriptRunner extends Thread { private final File file; private final String script; private final StringBuilder res; public int exitcode = -1; private Process exec; public ScriptRunner(File file, String script, StringBuilder res) { this.file = file; this.script = script; this.res = res; } @Override public void run() { try { file.createNewFile(); final String abspath = file.getAbsolutePath(); Runtime.getRuntime().exec("chmod 777 " + abspath).waitFor(); final OutputStreamWriter out = new OutputStreamWriter( new FileOutputStream(file)); if (new File("/system/bin/sh").exists()) { out.write("#!/system/bin/sh\n"); } out.write(script); if (!script.endsWith("\n")) out.write("\n"); out.write("exit\n"); out.flush(); out.close(); exec = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream( exec.getOutputStream()); os.writeBytes(abspath); os.flush(); os.close(); InputStreamReader r = new InputStreamReader( exec.getInputStream()); final char buf[] = new char[1024]; int read = 0; while ((read = r.read(buf)) != -1) { if (res != null) res.append(buf, 0, read); } r = new InputStreamReader(exec.getErrorStream()); read = 0; while ((read = r.read(buf)) != -1) { if (res != null) res.append(buf, 0, read); } if (exec != null) this.exitcode = exec.waitFor(); } catch (InterruptedException ex) { if (res != null) res.append("\nOperation timed-out"); } catch (Exception ex) { if (res != null) res.append("\n" + ex); } finally { destroy(); } } public synchronized void destroy() { if (exec != null) exec.destroy(); exec = null; } } }
View Code
作者:登天路
转载请说明出处:http://www.cnblogs.com/travellife/
相关文章推荐
- Android随笔之——用shell脚本模拟用户按键、触摸操作
- 用shell脚本模拟用户按键、触摸操作
- Android随笔之——模拟按键操作的几种方式
- Android手机上,利用bat脚本模拟用户操作
- shell脚本实现简单的模拟用户操作,未加检查点。
- Android随笔之——模拟按键操作的几种方式
- Android手机上,利用bat脚本模拟用户操作
- Shell脚本中实现切换用户并执行命令操作【转】
- Shell脚本中实现切换用户并执行命令操作
- shell脚本操作oracle删除表空间、创建表空间、删除用户
- shell脚本操作oracle删除表空间、创建表空间、删除用户
- Android用代码模拟系统物理按键长按操作(类似按键精灵)
- Android基于Socket无线遥控(2)--模拟触摸按键篇
- 如何使用shell脚本对android手机的操作---初级篇1
- adb shell 模拟按键,触摸事件
- 我的Android进阶之旅------>Android中通过adb shell input来模拟滑动、按键、点击事件
- shell整理(35)====模拟用户登录的打印菜单脚本
- linux之基础shell脚本编程4 字符串操作,变量赋值,配置用户环境
- 转:Android随笔之——使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)
- Shell脚本:实时监控用户操作