基本用法
基本命令
adb基本命令,基本语法如下:
adb [-d|-e|-s <serialNumber>] <command>
如果当前连接只有一个设备,可以直接省略掉[-d|-e|-s <serialNumber>]
这一部分,直接使用 adb <comman
。
为命令行指定目标设备
如果有多台设备或模拟器连接,需要指定目标设备
参数 | 含义 |
---|---|
-d | 指定当前唯一通过 USB 连接的 Android 设备为命令目标 |
-e | 指定当前唯一运行的模拟器为命令目标 |
-s <serialNumber> | 指定相应 serialNumber 号的设备/模拟器为命令目标 |
在多个设备/模拟器连接的情况下较常用的是 -s <serialNumber> 参数,serialNumber 可以通过 adb devices 命令获取。如:
$ adb devices
List of devices attached
cf668fa device
emulator-555 device
196.168.1.150:5555 device
这里的cf668fa
以及emulator-555
和196.168.1.150:5555
都称为serialNumber。
停止/启动
adb start-server
启动adb,但是由于系统会自动启动,无需主动调用
adb kill-server
停止adb,多用于PC存在多个adb时,全部关闭
查看adb的版本
adb version
运行后结果如下:
可见版本为1.0.40.
安装地址在
D:\SDK\platform-tools\adb.exe
.但是需要在环境变量中配置adb的path路径。
root权限
adb虽然可以用来做一些Root操作,但是前提是设备必须具备root权限,学习可以考虑用虚拟机。
命令:
adb root
恢复root:
adb unroot
设置adb的网络端口
命令:
adb -P <port> start-server
这个几乎很少使用,不知到具体用处,之后补充记录
设备连接
查询设备
查询当前adb连接的设备信息
adb devices
List of devices attached
0000119030001002 device
输出的组成格式为[serialNumber] [state]
,其中0000119030001002
为设备编号SN
,device
为设备的状态。设备的状态可以分为以下几种:
offline
—— 表示设备未连接成功或无响应。device
—— 设备已连接。注意这个状态并不能标识 Android 系统已经完全启动和可操作,在设备启动过程中设备实例就可连接到 adb,但启动完毕后系统才处于可操作状态。no device
—— 没有设备/模拟器连接。
该命令为常用命令,多会使用。
USB连接
USB连接就是通过USB线,以及adb来连接Android设备,也是开发工作中使用得最多的连接方式。一般手机需要打开[
设置」-「开发者选项」-「Android 调试」。如果没有该选项,可以到「设置」-「关于手机」连续点击「版本号」可以打开开发者选项。
USB无线
其实除了USB连接设备外,还可以通过无线网的方式连接,虽然开始需要USB线连接,但是想想可以离开USB线的限制,是不是也有一点小激动呢。操作步骤如下
- 首先,确认PC和设备是处于同一局域网下,比如同一个路由下的wiffi。这是非常重要的。
- 其次,将PC和设备通过USB连接在一起,通过
adb devices
确认是否连接成功. - 然后,让设备在555端口监听TCP/IP 连接,当然部分特殊设备端口不是555,酌情调整:
adb tcpip 555
- 之后,断开USB线连接
- 通过手机自身的设置」-「关于手机」-「状态信息」-「IP地址」或者(推荐后者)通过adb命令去获取设备的ip地址
adb shell ifconfig | grep Mask
. - 使用命令行和得到的IP地址连接设备
adb connect <device-ip-address>
<device-ip-address>
也就是之前找到的ip地址.
- 最后,使用
adb devices
检测是否成功连接设备
无线连接(root)
无线连接的首要条件就是需要root权限.所以一开始就是adb root
开启root权限。然后操作步骤与USB一样,但是无需连接USB线。
将 Android 设备与要运行 adb 的电脑连接到同一个局域网,比如连到同一个 WiFi。
- 首先,打开 Android 设备上的终端模拟器,在里面依次运行命令:
su
setprop service.adb.tcp.port 5555
再者,通过手机自身的设置」-「关于手机」-「状态信息」-「IP地址」或者(推荐后者)通过adb命令去获取设备的ip地址
adb shell ifconfig | grep Mask
.最后,在电脑上通过 adb 和 IP 地址连接 Android 设备。
adb connect <device-ip-address>
这里的<device-ip-address>
就是上一步中找到的设备 IP 地址。
如果能看到 connected to <device-ip-address>:
端口 这样的输出则表示连接成功。
Package管理
查阅应用列表
查阅应用列表的adb命令行模式如下:
adb shell pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]
前部分adb shell pm list packages
为获取当前设备中所有应用的package信息,后面为过滤符。其中支持的过滤参数列表整理如下:
参数 | 显示列表 |
---|---|
无 | 所有应用 |
-f | 显示应用关联的 apk 文件 |
-d | 只显示 disabled 的应用 |
-e | 只显示 enabled 的应用 |
-s | 只显示系统应用 |
-3 | 只显示第三方应用 |
-i | 显示应用的 installer |
-u | 包含已卸载应用 |
<FILTER> | 包名包含 <FILTER> 字符串 |
ps:<FILTER>
除了直接可以过滤外,还可以使用grep做筛选
比如:
adb shell pm list packages clouwalk
与
adb shell pm list packages |grep cloudwalk
(部分设备不支持)
安装应用
安装应用为常用的adb命令行,其格式如下:
adb install [-xxx] <apk_path>
其中xxx为修饰参数,用来指定应用apk的安装方式,具体可以有以下几种修饰方式:
参数 | 含义 |
---|---|
-l | 将应用安装到保护目录 /mnt/asec |
-r | 允许覆盖安装 |
-t | 允许安装 AndroidManifest.xml 里 application 指定 android:testOnly="true" 的应用 |
-s | 将应用安装到 sdcard |
-d | 允许降级覆盖安装 |
-g | 授予所有运行时权限 |
出现如Success
标识,代表安装成功。出现Failure [xxx]
,代表失败.常见的失败选项如下:
输出 | 含义 | 解决方法 |
---|---|---|
INSTALL_FAILED_ALREADY_EXISTS | 应用已经存在,或卸载了但没卸载干净 | adb install 时使用 -r 参数,或者先 adb uninstall <packagename> 再安装 |
INSTALL_FAILED_INVALID_APK | 无效的 APK 文件 | 检查apk文件的完整性和有效性 |
INSTALL_FAILED_INVALID_URI | 无效的 APK 文件名 | 确保 APK 命名文件名里无中文或特殊字符 |
INSTALL_FAILED_INSUFFICIENT_STORAGE | 空间不足 | 清理空间 |
INSTALL_FAILED_DUPLICATE_PACKAGE | 已经存在同名程序 | 更改应用名或adb uninstall <packagename> 再安装 |
INSTALL_FAILED_NO_SHARED_USER | 请求的共享用户不存在 | |
INSTALL_FAILED_UPDATE_INCOMPATIBLE | 以前安装过同名应用,但卸载时数据没有移除;或者已安装该应用,但签名不一致 | 先 adb uninstall <packagename> 再安装 |
INSTALL_FAILED_SHARED_USER_INCOMPATIBLE | 请求的共享用户存在但签名不一致 | |
INSTALL_FAILED_MISSING_SHARED_LIBRARY | 安装包使用了设备上不可用的共享库 | |
INSTALL_FAILED_REPLACE_COULDNT_DELETE | 替换时无法删除 | |
INSTALL_FAILED_DEXOPT | dex 优化验证失败或空间不足 | |
INSTALL_FAILED_OLDER_SDK | 设备系统版本低于应用要求 | |
INSTALL_FAILED_CONFLICTING_PROVIDER | 设备里已经存在与应用里同名的 content provider | |
INSTALL_FAILED_NEWER_SDK | 设备系统版本高于应用要求 | |
INSTALL_FAILED_TEST_ONLY | 应用是 test-only 的,但安装时没有指定 -t 参数 | |
INSTALL_FAILED_CPU_ABI_INCOMPATIBLE | 包含不兼容设备 CPU 应用程序二进制接口的 native code | |
INSTALL_FAILED_MISSING_FEATURE | 应用使用了设备不可用的功能 | |
INSTALL_FAILED_CONTAINER_ERROR | 1. sdcard 访问失败;<br />2. 应用签名与 ROM 签名一致,被当作内置应用。 | 1. 确认 sdcard 可用,或者安装到内置存储;<br />2. 打包时不与 ROM 使用相同签名。 |
INSTALL_FAILED_INVALID_INSTALL_LOCATION | 1. 不能安装到指定位置;<br />2. 应用签名与 ROM 签名一致,被当作内置应用。 | 1. 切换安装位置,添加或删除 -s 参数;<br />2. 打包时不与 ROM 使用相同签名。 |
INSTALL_FAILED_MEDIA_UNAVAILABLE | 安装位置不可用 | 一般为 sdcard,确认 sdcard 可用或安装到内置存储 |
INSTALL_FAILED_VERIFICATION_TIMEOUT | 验证安装包超时 | |
INSTALL_FAILED_VERIFICATION_FAILURE | 验证安装包失败 | |
INSTALL_FAILED_PACKAGE_CHANGED | 应用与调用程序期望的不一致 | |
INSTALL_FAILED_UID_CHANGED | 以前安装过该应用,与本次分配的 UID 不一致 | 清除以前安装过的残留文件 |
INSTALL_FAILED_VERSION_DOWNGRADE | 已经安装了该应用更高版本 | 使用 -d 参数 |
INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE | 已安装 target SDK 支持运行时权限的同名应用,要安装的版本不支持运行时权限 | |
INSTALL_PARSE_FAILED_NOT_APK | 指定路径不是文件,或不是以 .apk 结尾 | |
INSTALL_PARSE_FAILED_BAD_MANIFEST | 无法解析的 AndroidManifest.xml 文件 | |
INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION | 解析器遇到异常 | |
INSTALL_PARSE_FAILED_NO_CERTIFICATES | 安装包没有签名 | |
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES | 已安装该应用,且签名与 APK 文件不一致 | 先卸载设备上的该应用,再安装 |
INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING | 解析 APK 文件时遇到 CertificateEncodingException | |
INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME | manifest 文件里没有或者使用了无效的包名 | |
INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID | manifest 文件里指定了无效的共享用户 ID | |
INSTALL_PARSE_FAILED_MANIFEST_MALFORMED | 解析 manifest 文件时遇到结构性错误 | |
INSTALL_PARSE_FAILED_MANIFEST_EMPTY | 在 manifest 文件里找不到找可操作标签(instrumentation 或 application) | |
INSTALL_FAILED_INTERNAL_ERROR | 因系统问题安装失败 | |
INSTALL_FAILED_USER_RESTRICTED | 用户被限制安装应用 | 在开发者选项里将「USB安装」打开,如果已经打开了,那先关闭再打开。 |
INSTALL_FAILED_DUPLICATE_PERMISSION | 应用尝试定义一个已经存在的权限名称 | |
INSTALL_FAILED_NO_MATCHING_ABIS | 应用包含设备的应用程序二进制接口不支持的 native code | |
INSTALL_CANCELED_BY_USER | 应用安装需要在设备上确认,但未操作设备或点了取消 | 在设备上同意安装 |
INSTALL_FAILED_ACWF_INCOMPATIBLE | 应用程序与设备不兼容 | |
INSTALL_FAILED_TEST_ONLY | APK 文件是使用 Android Studio 直接 RUN 编译出来的文件 | 通过 Gradle 的 assembleDebug 或 assembleRelease 重新编译,或者 Generate Signed APK |
does not contain AndroidManifest.xml | 无效的 APK 文件 | |
is not a valid zip file | 无效的 APK 文件 | |
Offline | 设备未连接成功 | 先将设备与 adb 连接成功 |
unauthorized | 设备未授权允许调试 | |
error: device not found | 没有连接成功的设备 | 先将设备与 adb 连接成功 |
protocol failure | 设备已断开连接 | 先将设备与 adb 连接成功 |
Unknown option: -s | Android 2.2 以下不支持安装到 sdcard | 不使用 -s 参数 |
No space left on device | 空间不足 | 清理空间 |
Permission denied ... sdcard ... | sdcard 不可用 | |
signatures do not match the previously installed version; ignoring! | 已安装该应用且签名不一致 | 先卸载设备上的该应用,再安装 |
参考:PackageManager.java
adb install 实际是分三步完成:
push apk 文件到 /data/local/tmp。
调用 pm install 安装。
删除 /data/local/tmp 下的对应 apk 文件。
所以,必要的时候也可以根据这个步骤,手动分步执行安装过程。
卸载应用
命令:
adb uninstall [-k] <packagename>
<packagename>
表示应用的包名,-k
参数可选,表示卸载应用但保留数据和缓存目录。
命令示例:
adb uninstall com.qihoo360.mobilesafe
表示卸载设备上的360 手机卫士。
清除应用数据和缓存数据
adb shell pm clear <packagename>
例如:
adb shell pm clear com.tecent.mobleqq
这个命令就可以清除掉手机QQ上所有的本地缓存数据和应用数据。这个命令为常用命令
查看正在运行的service
adb shell dumpsys activity services [<packagename>]
<packagename>
参数不是必须的,指定<packagename>
表示查看与某个包名相关的 Services,不指定表示查看所有 Services。
<packagename>
不一定要给出完整的包名
查看应用详细信息
adb shell dumpsys package <packagename>
输出中包含很多信息,包括 Activity Resolver Table、Registered ContentProviders、包名、userId、安装后的文件资源代码等路径、版本信息、权限信息和授予状态、签名版本信息等。
<packagename>
表示应用包名。
查看应用安装途径
adb shell pm path <PACKAGE>
输出应用安装路径.效果如下:
应用交互
与应用交互的关键字为am <command>
命令,常用的command
命令如下:
command | 用途 |
---|---|
start [options] <INTENT> | 启动 <INTENT> 指定的 Activity |
startservice [options] <INTENT> | 启动 <INTENT> 指定的 Service |
broadcast [options] <INTENT> | 发送 <INTENT> 指定的广播 |
force-stop <packagename> | 停止 <packagename> 相关的进程 |
<INTENT>
参数很灵活,和写 Android 程序时代码里的 Intent 相对应。
用于决定 intent 对象的选项如下:
参数 | 含义 |
---|---|
-a <ACTION> | 指定 action,比如 android.intent.action.VIEW |
-c <CATEGORY> | 指定 category,比如 android.intent.category.APP_CONTACTS |
-n <COMPONENT> | 指定完整 component 名,用于明确指定启动哪个 Activity,如 com.example.app/.ExampleActivity |
启动应用/ 调起 Activity
adb shell am start [options] <INTENT>
例如:
adb shell am start -n com.tencent.mm/.ui.LauncherUI
该命令可以启动微信
启动service
adb shell am startservice [options] <INTENT>
例如:
adb shell am startservice -n com.tencent.mm/.plugin.accountsync.model.AccountAuthenticatorService
表示调起微信的某 Service。
另外一个典型的用例是如果设备上原本应该显示虚拟按键但是没有显示,可以试试这个:
adb shell am startservice -n com.android.systemui/.SystemUIService
停止service
adb shell am stopservice [options] <INTENT>
发送广播
adb shell am broadcast [options] <INTENT>
可以向所有组件广播,也可以只向指定组件广播。
例如,向所有组件广播 BOOT_COMPLETED:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
又例如,只向 org.mazhuang.boottimemeasure/.BootCompletedReceiver 广播 BOOT_COMPLETED:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -n org.mazhuang.boottimemeasure/.BootCompletedReceive
这类用法在测试的时候很实用,比如某个广播的场景很难制造,可以考虑通过这种方式来发送广播。
既能发送系统预定义的广播,也能发送自定义广播。如下是部分系统预定义广播及正常触发时机:
action | 触发时机 |
---|---|
android.net.conn.CONNECTIVITY_CHANGE | 网络连接发生变化 |
android.intent.action.SCREEN_ON | 屏幕点亮 |
android.intent.action.SCREEN_OFF | 屏幕熄灭 |
android.intent.action.BATTERY_LOW | 电量低,会弹出电量低提示框 |
android.intent.action.BATTERY_OKAY | 电量恢复了 |
android.intent.action.BOOT_COMPLETED | 设备启动完毕 |
android.intent.action.DEVICE_STORAGE_LOW | 存储空间过低 |
android.intent.action.DEVICE_STORAGE_OK | 存储空间恢复 |
android.intent.action.PACKAGE_ADDED | 安装了新的应用 |
android.net.wifi.STATE_CHANGE | WiFi 连接状态发生变化 |
android.net.wifi.WIFI_STATE_CHANGED | WiFi 状态变为启用/关闭/正在启动/正在关闭/未知 |
android.intent.action.BATTERY_CHANGED | 电池电量发生变化 |
android.intent.action.INPUT_METHOD_CHANGED | 系统输入法发生变化 |
android.intent.action.ACTION_POWER_CONNECTED | 外部电源连接 |
android.intent.action.ACTION_POWER_DISCONNECTED | 外部电源断开连接 |
android.intent.action.DREAMING_STARTED | 系统开始休眠 |
android.intent.action.DREAMING_STOPPED | 系统停止休眠 |
android.intent.action.WALLPAPER_CHANGED | 壁纸发生变化 |
android.intent.action.HEADSET_PLUG | 插入耳机 |
android.intent.action.MEDIA_UNMOUNTED | 卸载外部介质 |
android.intent.action.MEDIA_MOUNTED | 挂载外部介质 |
android.os.action.POWER_SAVE_MODE_CHANGED | 省电模式开启 |
(以上广播均可使用 adb 触发)
强制停止应用
命令:
adb shell am force-stop <packagename>
命令示例:
adb shell am force-stop com.qihoo360.mobilesafe
表示停止 360 安全卫士的一切进程与服务
文件管理
复制设备里的文件到本地
该命令为常用命令,多用于导出log日志和一些关键文件。
adb pull <设备里的文件路径> [电脑上的目录]
其中 电脑上的目录 参数可以省略,默认复制到当前目录。
复制电脑上的文件到设备
adb push <电脑上的文件路径> <设备里的目录>
其中电脑上的文件路径既可以是绝对路径也可以是相对路径。
模拟按键输入
在某些测试情况下,可以通过编写bat命令行来做相应的测试,这就需要模拟按键输入。并且在一些特殊的设备,没有物理按键的情况下,也需要模拟按键输入。该命令在adb shell
命令下的input
下,在adb下使用help可以得到如下的信息:
Usage: input [<source>] <command> [<arg>...]
The sources are:
mouse
keyboard
joystick
touchnavigation
touchpad
trackball
stylus
dpad
gesture
touchscreen
gamepad
The commands and default sources are:
text <string> (Default: touchscreen)
keyevent [--longpress] <key code number or name> ... (Default: keyboard)
tap <x> <y> (Default: touchscreen)
swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
press (Default: trackball)
roll <dx> <dy> (Default: trackball)
比如使用 adb shell input keyevent <keycode> 命令,不同的 keycode 能实现不同的功能,完整的 keycode 列表详见 KeyEvent,其中摘录部分比较常用的命令:
keycode | 含义 |
---|---|
3 | HOME 键 |
4 | 返回键 |
5 | 打开拨号应用 |
6 | 挂断电话 |
24 | 增加音量 |
25 | 降低音量 |
26 | 电源键 |
27 | 拍照(需要在相机应用里) |
64 | 打开浏览器 |
82 | 菜单键 |
85 | 播放/暂停 |
86 | 停止播放 |
87 | 播放下一首 |
88 | 播放上一首 |
122 | 移动光标到行首或列表顶部 |
123 | 移动光标到行末或列表底部 |
126 | 恢复播放 |
127 | 暂停播放 |
164 | 静音 |
176 | 打开系统设置 |
187 | 切换应用 |
207 | 打开联系人 |
208 | 打开日历 |
209 | 打开音乐 |
210 | 打开计算器 |
220 | 降低屏幕亮度 |
221 | 提高屏幕亮度 |
223 | 系统休眠 |
224 | 点亮屏幕 |
231 | 打开语音助手 |
276 | 如果没有 wakelock 则让系统休眠 |
下面是 input
命令的一些用法举例。
电源键
命令:
adb shell input keyevent 26
执行效果相当于按电源键。
菜单键
命令:
adb shell input keyevent 82
HOME 键
命令:
adb shell input keyevent 3
返回键
命令:
adb shell input keyevent 4
音量控制
增加音量:
adb shell input keyevent 24
降低音量:
adb shell input keyevent 25
静音:
adb shell input keyevent 164
媒体控制
播放/暂停:
adb shell input keyevent 85
停止播放:
adb shell input keyevent 86
播放下一首:
adb shell input keyevent 87
播放上一首:
adb shell input keyevent 88
恢复播放:
adb shell input keyevent 126
暂停播放:
adb shell input keyevent 127
点亮/熄灭屏幕
可以通过上文讲述过的模拟电源键来切换点亮和熄灭屏幕,但如果明确地想要点亮或者熄灭屏幕,那可以使用如下方法。
点亮屏幕:
adb shell input keyevent 224
熄灭屏幕:
adb shell input keyevent 223
滑动解锁
如果锁屏没有密码,是通过滑动手势解锁,那么可以通过 input swipe
来解锁。
命令(参数以机型 Nexus 5,向上滑动手势解锁举例):
adb shell input swipe 300 1000 300 500
参数 300 1000 300 500
分别表示起始点x坐标 起始点y坐标 结束点x坐标 结束点y坐标
。
输入文本
在焦点处于某文本框时,可以通过 input
命令来输入文本。
命令:
adb shell input text hello
现在 hello
出现在文本框了。
Android日志查看
从Android日志方面分为底层的 Linux 内核和Android 的日志。底层的 Linux 内核日志输出到 /proc/kmsg,Android 的日志输出到 /dev/log。,两者存储位置完全不一样。
Android日志
[adb] logcat [<option>] ... [<filter-spec>] ...
对于其中常用的用法如下:
按级别过滤日志
Android系统对于日志按照优先级(priority)进行分级,分级情况如下:
- V —— Verbose(最低,输出得最多)
- D —— Debug
- I —— Info
- W —— Warning
- E —— Error
- F —— Fatal
- S —— Silent(最高,啥也不输出)
其中常用的为前四种。排序为从低到高。使用时按某级别过滤日志则会将该级别及以上的日志输出。
比如,命令:
adb logcat *:W
会将 Warning、Error、Fatal 和 Silent 日志输出。
(注: 在 macOS 下需要给 *:W
这样以 *
作为 tag 的参数加双引号,如 adb logcat "*:W"
,不然会报错 no matches found: *:W
。)
按照tag和级别过滤日志
<filter-spec>
可以由多个 <tag>[:priority]
组成。
比如,命令:
adb logcat ActivityManager:I MyApp:D *:S
表示输出 tag ActivityManager
的 Info 以上级别日志,输出 tag MyApp
的 Debug 以上级别日志,及其它 tag 的 Silent 级别日志(即屏蔽其它 tag 日志)。