我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

目录

一、概述

二、常用命令

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

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#中如何使用远程调试和性能分析工具优化代码性能及解决方法

C#中如何使用远程调试和性能分析工具优化代码性能及解决方法引言:在软件开发过程中,优化代码的性能是非常重要的一项任务。通过代码优化,可以使程序运行更加高效,提高用户体验,并减少资源消耗。在C#中,我们可以利用远程调试和性能分析工具来帮助我们
2023-10-22

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录