返回顶部
首页 > 资讯 > 移动开发 >Android13 adb input 调试命令使用和源码解析
  • 422
分享到

Android13 adb input 调试命令使用和源码解析

adbandroid调试input 2023-09-24 18:09:52 422人浏览 八月长安
摘要

目录 一、概述 二、常用命令 2.1 输入文本 2.2 模拟按键 2.3 模拟点击 2.4 模拟滑动 2.5 模拟长按 2.6 模拟滚动 三、进阶用法 3.1 组合按键的用法 3.2 长按power键 3.3 输入中文 3.4 代码模拟发送

目录

一、概述

二、常用命令

2.1 输入文本

2.2 模拟按键

2.3 模拟点击

2.4 模拟滑动

2.5 模拟长按

2.6 模拟滚动

三、进阶用法

3.1 组合按键的用法

3.2 长按power键

3.3 输入中文

3.4 代码模拟发送按键

1. 方法1:

2. 方法2:

3. 方法3:

四、注意事项

五、源码解析

六、总结


好了 本篇作为Android 系统调试系列第一篇内容 , 我一直以为和认为Android系统工程师水平,基本可以用 调试水平 调试问题技巧来判断高低。

调试工具手法技巧作为Android程序员的瑞士军刀 必须先磨好刀 。

一、概述

adb shell input是一个命令,用于在Android设备上模拟用户输入。它可以用于自动化测试、调试和其他需要模拟用户输入的场景。通过adb shell input命令,可以模拟按键、滑动、触摸等操作。例如,adb shell input tap x y可以模拟在屏幕上点击坐标为(x,y)的位置。

adb shell input命令的格式如下:

adb shell input [] [-d DISPLAY_ID]  [...]

其中,是要模拟的事件的来源,可以是以下之一:

  • keyboard: 键盘
  • touchscreen: 触摸屏
  • trackball: 轨迹球

如果不指定来源,默认使用以下规则:

  • text: 触摸屏
  • keyevent: 键盘
  • tap: 触摸屏
  • swipe: 触摸屏
  • press: 轨迹球
  • roll: 轨迹球

-d DISPLAY_ID是指定要模拟事件的显示器ID,如果不指定,默认使用以下规则:

  • keyevent: 无效显示器(INVALID_DISPLAY)
  • 其他事件: 默认显示器(DEFAULT_DISPLAY)

是要模拟的事件类型,可以是以下之一:

  • text: 输入文本
  • keyevent: 模拟按键
  • tap: 模拟点击
  • swipe: 模拟滑动
  • press: 模拟长按
  • roll: 模拟滚动

是根据不同的事件类型指定的参数,例如坐标、按键码、文本内容等。

二、常用命令

2.1 输入文本

要在设备上输入文本,可以使用以下命令:

adb shell input text 

其中,是要输入的文本内容。注意,文本中不能包含空格或特殊字符,否则会导致错误或不完整的输入。如果需要输入空格或特殊字符,可以使用转义符\或者使用按键事件代替。

例如,要在设备上输入"Hello World!",可以使用以下命令:

adb shell input text Hello\ World\!

或者

adb shell input keyevent 36 # Hadb shell input keyevent 33 # eadb shell input keyevent 46 # ladb shell input keyevent 46 # ladb shell input keyevent 48 # oadb shell input keyevent 62 # SPACEadb shell input keyevent 55 # Wadb shell input keyevent 48 # oadb shell input keyevent 46 # radb shell input keyevent 37 # ladb shell input keyevent 32 # dadb shell input keyevent 56 # !

2.2 模拟按键

要在设备上模拟按键,可以使用以下命令:

adb shell input keyevent [--longpress|--doubletap] 

其中,--longpress--doubletap是可选的修饰符,分别表示长按和双击。是要模拟的按键的代码,可以是数字或字符串。例如,要在设备上模拟返回键,可以使用以下命令:

adb shell input keyevent KEYCODE_BACK


或者

adb shell input keyevent 4

 

要查看所有可用的按键代码,请参考 KeyEvent 文档
(仅限于Google官方的镜像 如果自己系统源码中自定义keycode 查不到的 要看自己的系统代码)。

2.3 模拟点击

要在设备上模拟点击某个坐标点,可以使用以下命令:

adb shell input tap  

其中,是要点击的屏幕坐标。例如,要在设备上点击(100,200)这个点,可以使用以下命令:

adb shell input tap 100 200

2.4 模拟滑动

要在设备上模拟从一个坐标点滑动到另一个坐标点,可以使用以下命令:

adb shell input swipe     []

其中,是滑动的起始坐标,是滑动的结束坐标,是滑动的持续时间,单位是毫秒,可选参数。例如,要在设备上从(100,200)滑动到(300,400),并持续2秒,可以使用以下命令:

adb shell input swipe 100 200 300 400 2000

2.5 模拟长按

要在设备上模拟长按某个坐标点,可以使用以下命令:

adb shell input press  

其中,是要长按的屏幕坐标。例如,要在设备上长按(100,200)这个点,可以使用以下命令:

adb shell input press 100 200

2.6 模拟滚动

要在设备上模拟滚动屏幕,可以使用以下命令:

adb shell input roll  

其中,是水平和垂直方向的滚动距离。例如,要在设备上向右滚动50个像素,向下滚动100个像素,可以使用以下命令:

adb shell input roll 50 100

三、进阶用法

3.1 组合按键的用法

要在设备上模拟组合按键,例如Ctrl+C、Alt+Tab等,可以使用以下命令:

adb shell input keyevent --longpress   [ ...]

或者

adb shell input keycombination [-t duration(ms)]   [ ...]

其中,--longpress-t duration(ms)是可选的修饰符,分别表示长按和指定按键间隔时间。是要模拟的第一个按键的代码,是要模拟的第二个按键的代码,以此类推。注意,在使用keycombination命令时,按键顺序很重要。例如,要在设备上模拟Ctrl+C,可以使用以下命令:

adb shell input keyevent --longpress KEYCODE_CTRL_LEFT KEYCODE_C

或者

adb shell input keycombination -t 100 KEYCODE_CTRL_LEFT KEYCODE_C

要查看所有可用的按键代码,请参考 KeyEvent 文档。

3.2 长按power键

要在设备上模拟长按power键,可以使用以下命令:

adb shell input keyevent --longpress KEYCODE_POWER

或者

adb shell input keyevent --longpress 26

这样可以弹出关机菜单或者其他功能,根据不同设备的设置而定。

如果想要直接关机或者重启,可以使用以下命令:

adb shell reboot -p # 关机adb shell reboot # 重启

3.3 输入中文

要在设备上输入中文,不能直接使用以下命令:

adb shell input text 

因为这个命令只支持ASCII字符集,不支持中文或其他非ASCII字符。如果强行输入中文,会导致乱码或者错误。

要输入中文,有两种方法:

  • 方法一:使用am broadcast命令发送一个广播,携带要输入的中文内容作为extra数据,然后在设备上安装一个接收该广播的应用,并在接收到广播后调用InputMethodManagershowSoftInput()方法来弹出软键盘,并使用InstrumentationsendStringSync()方法来输入中文。这种方法需要编写一个应用,并且需要root权限。
  • 方法二:使用adb push命令将要输入的中文内容保存到一个文件中,并推送到设备上的某个目录下,然后使用cat命令读取该文件的内容,并通过管道符|将其传递给input text命令。这种方法不需要编写应用,也不需要root权限。

例如,要在设备上输入"你好",可以使用以下命令:

echo "你好" > hello.txt # 在电脑上创建一个文件并写入你好(windows直接写进去就完事)adb push hello.txt /sdcard/ # 将文件推送到设备上的sdcard目录下adb shell cat /sdcard/hello.txt | tr -d '\n' | xargs -0 adb shell input text # 读取文件内容并传递给input text命令

3.4 代码模拟发送按键

1. 方法1:

使用Instrumentation类的sendKeySync()方法,这个方法会创建一个KeyEvent对象,并通过Instrumentation类的injectInputEvent()方法将其注入到系统中。这个方法需要具有INJECT_EVENTS权限,否则会抛出安全异常。这个方法适用于普通的按键事件,例如:

Instrumentation inst = new Instrumentation();inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A));inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A));
2. 方法2:

使用InputManager类的injectInputEvent()方法,这个方法会直接将一个KeyEvent对象注入到系统中,不经过Instrumentation类的处理。这个方法也需要具有INJECT_EVENTS权限,否则会抛出安全异常。这个方法适用于更复杂的按键事件,例如组合键、长按、双击等,需要自己创建多个KeyEvent对象,并设置相应的属性和时间间隔,并调用相应的方法进行注入。例如:

InputManager im = InputManager.getInstance();// 模拟发送Ctrl+C组合键final long now = SystemClock.uptimeMillis();// 按下Ctrlim.injectInputEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CTRL_LEFT,        0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD),        InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);// 按下Cim.injectInputEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_C,        0, KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON,        KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD),        InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);// 抬起Cim.injectInputEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_C,        0, KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON,        KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD),        InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);// 抬起Ctrlim.injectInputEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_CTRL_LEFT,        0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD),        InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3. 方法3:

随便搞个ShellUtils工具类 , 网上代码非常多 这种方法要系统root的。

ShellUtils.execCommand("input keyevent 224",true);

系统应用或具有系统签名的应用(app)以及app的UID和GID组对于能否模拟发送输入事件具有影响。通常,只有属于system或shell组的app才能将输入事件注入到系统中。可以使用Process类的myUid()和myGid()方法获取app的UID和GID,并使用Process类的getGidForName()方法获取system或shell组的GID。如果app的UID是0(即root用户)或者GID是system或shell组的GID,那么就可以进行输入事件的注入;否则不可以。

四、注意事项

在使用adb shell input命令时,有一些注意事项需要了解:

  • adb shell input命令只能模拟基本的输入事件,不能模拟复杂的手势或多点触控等操作。
  • adb shell input命令只能模拟用户在设备上的操作,不能模拟设备的物理状态,例如旋转、摇晃、倾斜等。
  • adb shell input命令只能模拟用户在当前屏幕上的操作,不能模拟用户在其他应用或界面上的操作。
  • adb shell input命令只能模拟用户在设备上的操作,不能模拟用户在外接设备上的操作,例如键盘、鼠标、手柄等。
  • adb shell input命令只能模拟用户在设备上的操作,不能模拟用户对设备的语音或人脸等输入。

如果需要模拟更高级或更复杂的输入事件,可以考虑使用其他工具或方法,例如:

  • 使用uiautomatormonkeyrunner自动化测试框架来编写和执行测试脚本。
  • 使用“Android投屏工具”ARDC等工具来远程控制设备,并在电脑上进行操作。

五、源码解析

adb shell input命令在Android 13中已经不再是一个单独的可执行文件,而是作为一个ShellCommand的子类,被集成到了InputManagerService中。这样做的好处是可以减少进程间通信的开销,提高输入事件的处理效率。源码改到了frameworks/base/services/core/java/com/android/server/input/InputShellCommand.java中,在这个文件中定义了一个InputShellCommand类,继承了ShellCommand类,并实现了各种事件类型的处理方法。例如:

  • onCommand(String cmd):这个函数是ShellCommand类的抽象方法,用于根据输入的命令和参数来执行相应的操作。这个函数首先解析输入源和显示ID(如果有的话),然后根据命令的类型,调用不同的runXXX方法来执行具体的操作。
  • onHelp():这个函数是ShellCommand类的抽象方法,用于打印帮助信息。这个函数向输出流输出adb shell input命令的用法和参数说明。
    --------只关注重点函数 下面的
  • runXXX(int inputSource, int displayId):这些函数用于执行不同类型的命令,例如text、keyevent、tap、swipe等。它们会获取相应的参数,并调用sendXXX方法发送相应的输入事件。
  • sendXXX(int inputSource, ...):这些函数用于发送不同类型的输入事件,例如文本、按键、点击、滑动等。它们会根据参数创建KeyEvent或MotionEvent对象,并设置其属性,并调用injecTKEyEvent或injectMotionEvent方法将其注入到系统中。
  • injectKeyEvent(KeyEvent event):这个函数用于同步注入一个键盘事件到系统中,它会使用InputManager类的getInstance()和injectInputEvent()方法来实现。
  • injectKeyEventAsync(KeyEvent event):这个函数用于异步注入一个键盘事件到系统中,它也会使用InputManager类的getInstance()和injectInputEvent()方法来实现,但是使用了INJECT_INPUT_EVENT_MODE_ASYNC模式,以便让系统的拦截器能够处理该事件。
  • injectMotionEvent(int inputSource, int action, long downTime, long when,
    float x, float y, float pressure, int displayId):这个函数用于注入一个动作事件到系统中,它会使用MotionEvent类的obtain()方法来创建一个MotionEvent对象,并设置其输入设备ID、输入源和显示ID等属性,并使用InputManager类的getInstance()和injectInputEvent()方法来实现。

所有的事件处理方法最终都会调用InputManagerService的内部方法来将输入事件注入到系统中。InputManagerService的源码位于frameworks/base/services/core/java/com/android/server/input/InputManagerService.java中,在这个文件中定义了一个InputManagerService类,实现了各种输入事件的管理和分发逻辑。(太复杂了 有空 再分析这块内容)

通过以上源码分析,可以了解到Android 13系统是如何接收、分发和处理adb shell input命令模拟的输入事件的。这些源码也可以帮助大家更好地理解adb shell input命令的原理和限制。

六、总结

本章重点Android adb input 调试命令的使用和源码分析。可以利用这些命令来模拟用户在设备上的各种操作,从而进行测试、调试或其他目的。同时,也可以通过阅读源码来深入了解Android 13系统的输入事件管理机制。希望这篇文章对大家有所帮助,如果还有其他问题,请随时向我提问 如果有错误请指正哈 !。

来源地址:https://blog.csdn.net/SHH_1064994894/article/details/131725982

--结束END--

本文标题: Android13 adb input 调试命令使用和源码解析

本文链接: https://lsjlt.com/news/417034.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作