一、ADB是什么?
adb 稱之為:Android 調試橋 (Android Debug Bridge )是一種允許模擬器或已連接的 Android 設備進行通信的命令行工具,它可為各種設備操作提供便利,如安裝和調試應用,並提供對 Unix shell
(可用來在模擬器或連接的設備上運行各種命令)的訪問。可以在Android SDK/platform-tools
中找到 adb
工具或下載 ADB Kits 。
注: 有部分命令的支持情況可能與 Android 系統版本及定制 ROM 的實現有關。
二、ADB有什么作用?
ADB
是 Android SDK
里的一個工具, 用這個工具可以直接操作管理Android模擬器或者真實的Android設備。它的主要功能有:
- 在設備上運行Shell命令;
- 將本地APK軟件安裝至模擬器或Android設備;
- 管理設備或手機模擬器上的預定端口;
- 在設備或手機模擬器上復制或粘貼文件。
ADB
是一個客戶端-服務器程序
程序,包括三個組件:
- 客戶端:該組件發送命令。客戶端在開發計算機上運行。您可以通過發出 adb 命令從命令行終端調用客戶端。
- 后台程序:該組件在設備上運行命令。后台程序在每個模擬器或設備實例上作為后台進程運行。
- 服務器:該組件管理客戶端和后台程序之間的通信。服務器在開發計算機上作為后台進程運行。
三、ADB命令語法
adb 命令的基本語法如下:
adb [-d|-e|-s <serial-number>] <command>
單一設備/模擬器連接
如果只有一個設備/模擬器連接時,可以省略掉 [-d|-e|-s <serial-number>]
這一部分,直接使用 adb <command>
。
多個設備/模擬器連接
如果有多個設備/模擬器連接,則需要為命令指定目標設備,下表是指定目標設備的命令選項:
參數 | 含義 |
---|---|
-d | 指定當前唯一通過 USB 連接的 Android 設備為命令目標 |
-e | 指定當前唯一運行的模擬器為命令目標 |
-s <serial-number> |
指定相應設備序列號的設備/模擬器為命令目標 |
在多個設備/模擬器連接的情況下較常用的是 -s <serial-number>
參數,serial-number
是指設備的設備序列號,可以通過 adb devices
命令獲取。
4.1 基本命令
4.1.1 查看adb的版本信息
adb version
4.1.2 啟動adb
adb start-server
一般無需手動執行此命令,在運行 adb 命令時若發現 adb server 沒有啟動會自動調起。
4.1.3 停止adb
adb kill-server
4.1.4 以 root 權限運行 adbd
adb root
4.1.5 指定 adb server 的網絡端口
adb -P <port> start-server
ADB的默認端口為 5037。
4.1.5 查詢已連接的設備/模擬器列表
adb devices
4.2 應用管理
4.2.1 查看應用列表
查看應用列表的基本命令格式是:
adb shell pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]
adb shell pm list packages
后面可以跟一些可選參數進行過濾查看不同的列表,可用參數及含義如下:
參數 | 顯示列表 |
---|---|
無 | 所有應用 |
-f | 顯示應用關聯的 apk 文件 |
-d | 只顯示 disabled 的應用 |
-e | 只顯示 enabled 的應用 |
-s | 只顯示系統應用 |
-3 | 只顯示第三方應用 |
-i | 顯示應用的 installer |
-u | 包含已卸載應用 |
<filter> |
包名包含 <filter> 字符串 |
4.2.1.1 查看所有應用
adb shell pm list packages
4.2.1.2 查看系統應用
adb shell pm list packages -s
4.2.1.3 查看第三方應用
adb shell pm list packages -3
4.2.1.4 包名包含某字符串的應用
比如要查看包名包含字符串 huawei
的應用列表,命令:
adb shell pm list packages huawei
4.2.2 安裝應用
安裝應用的基本命令格式是:
adb install [-l] [-r] [-t] [-s] [-d] [-g] <apk-file>
adb install
后面可以跟一些可選參數來控制安裝 APK 的行為,可用參數及含義如下:
參數 | 含義 |
---|---|
-l | 將應用安裝到保護目錄 /mnt/asec |
-r | 允許覆蓋安裝 |
-t | 允許安裝 AndroidManifest.xml 里 application 指定 android:testOnly="true" 的應用 |
-s | 將應用安裝到 sdcard |
-d | 允許降級覆蓋安裝 |
-g | 授予所有運行時權限 |
運行命令后可以看到輸出內容,包含安裝進度和狀態,安裝狀態如下:
Success
:代表安裝成功。Failure
:代表安裝失敗。 APK 安裝失敗的情況有很多,Failure
狀態之后有安裝失敗輸出代碼。常見安裝失敗輸出代碼、含義及可能的解決辦法如下:
輸出代碼 | 含義 | 解決辦法 |
---|---|---|
INSTALL_FAILED_ALREADY_EXISTS | 應用已經存在,或卸載了但沒卸載干凈 | adb install 時使用 -r 參數,或者先 adb uninstall <packagename> 再安裝 |
INSTALL_FAILED_INVALID_APK | 無效的 APK 文件 | |
INSTALL_FAILED_INVALID_URI | 無效的 APK 文件名 | 確保 APK 文件名里無中文 |
INSTALL_FAILED_INSUFFICIENT_STORAGE | 空間不足 | 清理空間 |
INSTALL_FAILED_DUPLICATE_PACKAGE | 已經存在同名程序 | |
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 訪問失敗; 2. 應用簽名與 ROM 簽名一致,被當作內置應用。 |
1. 確認 sdcard 可用,或者安裝到內置存儲; 2. 打包時不與 ROM 使用相同簽名。 |
INSTALL_FAILED_INVALID_INSTALL_LOCATION | 1. 不能安裝到指定位置; 2. 應用簽名與 ROM 簽名一致,被當作內置應用。 |
1. 切換安裝位置,添加或刪除 -s 參數;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 | 用戶被限制安裝應用 | |
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! | 已安裝該應用且簽名不一致 | 先卸載設備上的該應用,再安裝 |
adb install
實際是分三步完成:
- push apk 文件到 /data/local/tmp。
- 調用 pm install 安裝。
- 刪除 /data/local/tmp 下的對應 apk 文件。
4.2.3 卸載應用
卸載應用的基本命令格式是:
adb uninstall [-k] <package-name>
<package-name>
表示應用的包名,-k
參數可選,表示卸載應用但保留數據和緩存目錄。
4.2.4 清除應用數據與緩存
adb shell pm clear <package-name>
<package-name>
表示應用名包,這條命令的效果相當於在設置里的應用信息界面點擊了「清除緩存」和「清除數據」。
4.2.5 查看前台 Activity
adb shell dumpsys activity activities | grep mFocusedActivity
4.2.6 查看正在運行的 Services
adb shell dumpsys activity services [<package-name>]
<package-name>
參數不是必須的,指定 <package-name>
表示查看與某個包名相關的 Services,不指定表示查看所有 Services。<package-name>
不一定要給出完整的包名,可以只給一部分,那么所給包名相關的 Services 都會列出來。
4.2.7 查看應用詳細信息
adb shell dumpsys package <package-name>
<package-name>
表示應用包名。運行次命令的輸出中包含很多信息,包括 Activity Resolver Table、Registered ContentProviders、包名、userId、安裝后的文件資源代碼等路徑、版本信息、權限信息和授予狀態、簽名版本信息等。
4.2.7 查看應用安裝路徑
adb shell pm path <package-name>
4.3 與應用交互
與應用交互主要是使用 am <command>
命令,常用的 <command>
如下:
command | 用途 |
---|---|
start [options] <intent> |
啟動 <intent> 指定的 Activity |
startservice [options] <intent> |
啟動 <intent> 指定的 Service |
broadcast [options] <intent> |
發送 <intent> 指定的廣播 |
force-stop <package-name> |
停止 <package-name> 相關的進程 |
<intent>
參數很靈活,和寫 Android 程序時代碼里的 Intent 相對應。
用於決定 intent 對象的選項如下:
參數 | 含義 |
---|---|
-a <action> |
指定 action,比如 android.intent.action.VIEW |
-c <category> |
指定 category,比如 android.intent.category.APP_CONTACTS |
-n <component> |
指定完整 component 名,用於明確指定啟動哪個 Activity |
<intent>
里還能帶數據,就像寫代碼時的 Bundle 一樣:
參數 | 含義 |
---|---|
--esn <extra-key> |
null 值(只有 key 名) |
-e|--es <extra-key> <extra-string-value> |
string 值 |
--ez <extra-key> <extra-boolean-value> |
boolean 值 |
--ei <extra-key> <extra-int-value> |
integer 值 |
--el <extra-key> <extra-long-value> |
long 值 |
--ef <extra-key> <extra-float-value> |
float 值 |
--eu <extra-key> <extra-uri-value> |
URI |
--ecn <extra-key> <extra-component-name-value> |
component name |
--eia <extra-key> <extra-int-value>[,<extra-int-value...] |
integer 數組 |
--ela <extra-key> <extra-long-value>[,<extra-long-value...] |
long 數組 |
4.3.1 啟動應用/ 調起 Activity
adb shell am start [options] <intent>
例如:
adb shell am start -a android.settings.SETTINGS # 打開系統設置頁面
adb shell am start -a android.intent.action.DIAL -d tel:10086 # 打開撥號頁面
adb shell am start -n com.android.mms/.ui.ConversationList # 打開短信會話列表
options 是一些改變其行為的選項,支持的可選參數及含義如下:
選項 | 含義 |
---|---|
-D | 啟用調試 |
-W | 等待啟動完成 |
--start-profiler file |
啟動分析器並將結果發送到 file |
-P file |
類似於 --start-profiler,但當應用進入空閑狀態時分析停止 |
-R count |
重復 Activity 啟動次數 |
-S | 啟動 Activity 前強行停止目標應用 |
--opengl-trace | 啟用 OpenGL 函數的跟蹤 |
--user user_id | current |
指定要作為哪個用戶運行;如果未指定,則作為當前用戶運行 |
4.3.2 調起 Service
adb shell am startservice [options] <intent>
一個典型的用例是如果設備上原本應該顯示虛擬按鍵但是沒有顯示,可以試試這個:
adb shell am startservice -n com.android.systemui/.SystemUIService
4.3.3 停止 Service
adb shell am stopservice [options] <intent>
4.3.4 強制停止應用
adb shell am force-stop <packagename>
4.4 文件管理
4.4.1 從模擬器/設備下載指定的文件到計算機
從模擬器/設備下載指定的文件到計算機的基本命令格式是:
adb pull <remote> [local]
參數說明:
remote
: 模擬器/設備里的文件路徑local
:計算機上的目錄,參數可以省略,默認復制到當前目錄
例如,將 /sdcard/yibijizhang.apk 下載到計算機的當前目錄:
adb pull /sdcard/yibijizhang.apk
將 /sdcard/yibijizhang.apk 下載到計算機的當前目錄(目錄需存在):
adb pull /sdcard/yibijizhang.apk D:\Download
4.4.2 將指定的文件從計算機上傳到模擬器/設備
將指定的文件從計算機上傳到模擬器/設備的基本命令格式是:
adb push <local> <remote>
參數說明:
local
:計算機上的文件路徑remote
: 模擬器/設備里的目錄
例如,將 D:\Download\
adb push <local> <remote>
下載到設備的/sdcard/music/目錄:
adb push D:\Download\
adb push <local> <remote>
/sdcard/music/
4.4.4 列出指定目錄的內容
列出模擬器/設備上指定目錄的內容的基本命令格式是:
adb shell ls [options] <directory>
<directory>
表示指定目錄,可以省略,表示列出根目錄下的所有文件和目錄。 adb shell ls
后面可以跟一些可選參數進行過濾查看不同的列表,可用參數及含義如下:
參數 | 顯示列表 |
---|---|
無 | 列出目錄下的所有文件和目錄 |
-a | 列出目錄下的所有文件(包括隱藏的) |
-i | 列出目錄下的所有文件和索引編號 |
-s | 列出目錄下的所有文件和文件大小 |
-n | 列出目錄下的所有文件及其 UID和 GID |
-R | 列出目錄下的所有子目錄中的文件 |
4.4.5 切換到目標目錄
adb shell cd <directory>
第一步:執行adb shell
命令; 第二步:執行cd <directory>
命令切換到目標目錄。
4.4.6 刪除文件或目錄
adb shell rm [options] <files or directory>
第一步:執行adb shell
命令; 第二步:執行rm [options] <files or directory>
命令刪除文件或目錄。
rm
后面可以跟一些可選參數進行不同的操作,可用參數及含義如下:
參數 | 含義 |
---|---|
無 | 刪除文件 |
-f | 強制刪除文件,系統不提示 |
-r | 強制刪除指定目錄中的所有文件和子目錄 |
-d | 刪除指定目錄,即使它是一個非空目錄 |
-i | 交互式刪除,刪除前提示 |
rm -d
等同於 rmdir
命令,有些版本不包含-d
參數。
4.4.7 創建目錄
adb shell mkdir [options] <directory-name>
第一步:執行adb shell
命令; 第二步:執行mkdir [options] <directory-name>
命令創建目錄。 mkdir
后面可以跟一些可選參數進行不同的操作,可用參數及含義如下:
參數 | 含義 |
---|---|
無 | 創建指定目錄 |
-m | 創建指定目錄並賦予讀寫權限 |
-p | 創建指定目錄及其父目錄 |
4.4.8 創建空文件或改變文件時間戳
adb shell touch [options] <file>
第一步:執行adb shell
命令; 第二步:執行touch [options] <file>
命令創建空文件或改變文件時間戳。
可通過ls -n <directory>
命令查看文件的時間。
4.4.9 輸出當前目錄路徑
adb shell pwd
第一步:執行adb shell
命令; 第二步:執行pwd
命令輸出當前目錄路徑。
4.4.10 復制文件和目錄
adb shell cp [options] <source> <dest>
第一步:執行adb shell
命令; 第二步:執行cp [options] <source> <dest>
命令復制文件和目錄。 參數說明:
source
:源文件路徑dest
: 目標文件路徑
4.4.11 移動或重命名文件
adb shell mv [options] <source> <dest>
第一步:執行adb shell
命令; 第二步:執行mv [options] <source> <dest>
命令移動或重命名文件。 參數說明:
source
:源文件路徑dest
: 目標文件路徑
4.5 網絡管理
4.5.1 查看網絡統計信息
adb shell netstat
也可以將網絡統計信息輸出到指定文件:
adb shell netstat><file-path>
例如,可以通過 adb shell netstat>D:\netstat.log
將日志輸出到 D:\netstat.log
中。
4.5.2 測試兩個網絡間的連接和延遲
ping
命令的格式如下:
adb shell ping [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
[-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
[-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
[-w deadline] [-W timeout] [hop1 ...] destination
復制代碼
例如,ping一個域名:
adb shell ping www.baidu.com
不結束的話會一直ping下去,可以按 Ctrl + C
停止ping操作。
也可以指定ping的次數:
adb shell ping -c 4 www.baidu.com
4.5.3 通過配置文件配置和管理網絡連接
netcfg
命令的格式如下:
adb shell netcfg [<interface> {dhcp|up|down}]
輸出示例:
rmnet_ims10 DOWN 0.0.0.0/0 0x00001002
rmnet_ims00 DOWN 0.0.0.0/0 0x00001002
rmnet_tun04 DOWN 0.0.0.0/0 0x00001002
rmnet_tun03 DOWN 0.0.0.0/0 0x00001002
rmnet_tun02 DOWN 0.0.0.0/0 0x00001002
rmnet_tun01 DOWN 0.0.0.0/0 0x00001002
rmnet_tun00 DOWN 0.0.0.0/0 0x00001002
rmnet_tun14 DOWN 0.0.0.0/0 0x00001002
rmnet_tun13 DOWN 0.0.0.0/0 0x00001002
rmnet_tun12 DOWN 0.0.0.0/0 0x00001002
rmnet_tun11 DOWN 0.0.0.0/0 0x00001002
rmnet_tun10 DOWN 0.0.0.0/0 0x00001002
rmnet1 DOWN 0.0.0.0/0 0x00001002
rmnet0 DOWN 0.0.0.0/0 0x00001002
rmnet4 DOWN 0.0.0.0/0 0x00001002
rmnet3 DOWN 0.0.0.0/0 0x00001002
rmnet2 DOWN 0.0.0.0/0 0x00001002
rmnet6 DOWN 0.0.0.0/0 0x00001002
rmnet5 DOWN 0.0.0.0/0 0x00001002
dummy0 UP 0.0.0.0/0 0x000000c3
rmnet_r_ims10 DOWN 0.0.0.0/0 0x00001002
rmnet_r_ims00 DOWN 0.0.0.0/0 0x00001002
rmnet_emc0 DOWN 0.0.0.0/0 0x00001002
lo UP 127.0.0.1/8 0x00000049
sit0 DOWN 0.0.0.0/0 0x00000080
wlan0 UP 10.0.38.176/23 0x00001043
復制代碼
4.5.4 顯示、操作路由、設備、策略路由和隧道
ip
命令的格式如下:
adb shell ip [ options ] object
-
options := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |-f[amily] { inet | inet6 | ipx | dnet | link } |-l[oops] { maximum-addr-flush-attempts } |-o[neline] | -t[imestamp] | -b[atch] [filename] |-rc[vbuf] [size]}
-
object := { link | addr | addrlabel | route | rule | neigh | ntable |tunnel | tuntap | maddr | mroute | mrule | monitor | xfrm |netns | l2tp }
options
是一些修改ip行為或者改變其輸出的選項。所有的選項都是以-字符開頭,分為長、短兩種形式,支持的可選參數及含義如下:
選項 | 含義 |
---|---|
-V,-Version | 打印ip的版本並退出 |
-s,-stats,-statistics | 輸出更為詳盡的信息(如果這個選項出現兩次或者多次,輸出的信息將更為詳盡) |
-f,-family | 強調使用的協議種類(包括:inet、inet6或者link) |
-4 | 是-family inet的簡寫 |
-6 | 是-family inet6的簡寫 |
-0 | 是-family link的簡寫 |
-o,-oneline | 對每行記錄都使用單行輸出,回行用字符代替 |
-r,-resolve | 查詢域名解析系統,用獲得的主機名代替主機IP地址 |
object
是你要管理或者獲取信息的對象。目前ip認識的對象包括:
參數 | 顯示列表 |
---|---|
link | 網絡設備 |
address | 一個設備的協議(IP或者IPV6)地址 |
neighbour | ARP或者NDISC緩沖區條目 |
route | 路由表條目 |
rule | 路由策略數據庫中的規則 |
maddress | 多播地址 |
mroute | 多播路由緩沖區條目 |
tuntap | 管理 TUN/TAP 設備 |
netns | 管理網絡空間 |
例如,查看 WiFi IP
地址:
adb shell ip -f inet addr show wlan0
4.6 模擬按鍵/輸入
在 adb shell
里有個很實用的命令叫 input
,通過它可以做一些有趣的事情。 可以執行adb shell input
命令查看完整 help 信息如下:
Usage: input [<source>] <command> [<arg>...]
The sources are:
dpad
keyboard
mouse
touchpad
gamepad
touchnavigation
joystick
touchscreen
stylus
trackball
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)
draganddrop <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
命令的一些用法舉例。
4.6.1 電源鍵
adb shell input keyevent 26
執行效果相當於按電源鍵。
4.6.2 菜單鍵
adb shell input keyevent 82
4.6.3 HOME 鍵
adb shell input keyevent 3
4.6.4 返回鍵
adb shell input keyevent 4
4.6.5 音量控制
- 增加音量:
adb shell input keyevent 24
復制代碼
- 降低音量:
adb shell input keyevent 25
- 靜音:
adb shell input keyevent 16
4.6.6 媒體控制
- 播放/暫停:
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
4.6.7 點亮/熄滅屏幕
- 點亮屏幕:
adb shell input keyevent 224
- 熄滅屏幕:
adb shell input keyevent 223
4.6.8 滑動解鎖
如果鎖屏沒有密碼,是通過滑動手勢解鎖,那么可以通過 input swipe
來解鎖。 命令(向上滑動手勢解鎖舉例):
adb shell input swipe 300 1000 300 500
參數 300 1000 300 500
分別表示起始點x坐標 起始點y坐標 結束點x坐標 結束點y坐標
。
4.6.9 輸入文本
在焦點處於某文本框時,可以通過 input
命令來輸入文本。
adb shell input text hello
4.7 日志打印
Android 系統的日志分為兩部分,底層的 Linux 內核日志輸出到 /proc/kmsg,Android 的日志輸出到 /dev/log。
4.7.1 Android 日志
查看 Android 設備系統屬性的基本命令格式是:
adb logcat [option] [filter-specs]
如果需要停止 logcat
日志打印,可以按 Ctrl + C
停止日志監控。
4.7.1.1 按級別過濾日志
按級別過濾日志的基本命令格式是:
adb logcat [filter-specs]
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
。)
4.7.1.2 按 tag 和級別過濾日志
按 tag 和級別過濾日志的基本命令格式是:
adb logcat [tag:level] [tag:level] ...
復制代碼
比如,命令:
adb logcat ActivityManager:I MyApp:D *:S
復制代碼
表示輸出 tag ActivityManager
的 Info 以上級別日志,輸出 tag MyApp
的 Debug 以上級別日志,及其它 tag 的 Silent 級別日志(即屏蔽其它 tag 日志)。
4.7.1.3 將日志格式化輸出
可以用 adb logcat -v <format>
選項指定日志輸出格式。
日志支持按以下幾種 <format>
:
參數 | 顯示格式 |
---|---|
brief | <priority>/<tag>(<pid>): <message> |
process | <priority>(<pid>) <message> |
tag | <priority>/<tag>: <message> |
raw | <message> |
time | <datetime> <priority>/<tag>(<pid>): <message> |
threadtime | <datetime> <pid> <tid> <priority> <tag>: <message> |
long | [ <datetime> <pid>:<tid> <priority>/<tag> ] <message> |
日志格式默認為 brief
,指定格式可與上面的過濾同時使用。比如:
adb logcat -v long ActivityManager:I *:S
復制代碼
4.7.1.3 清空已存在的日志
adb logcat -c
復制代碼
4.7.1.4 將日志顯示在控制台
adb logcat -d
復制代碼
4.7.1.5 將日志輸出到文件
adb logcat -f <file-path>
復制代碼
4.7.1.6 加載一個可使用的日志緩沖區供查看
adb logcat -b <Buffer>
復制代碼
Android log
輸出量巨大,特別是通信系統的log,因此,Android把log輸出到不同的緩沖區中,目前定義了四個log緩沖區:
緩沖區 | 含義 |
---|---|
Radio | 輸出通信系統的 log |
System | 輸出系統組件的 log |
Event | 輸出 event 模塊的 log |
Main | 所有 java 層的 log 以及不屬於上面3層的 log |
緩沖區主要給系統組件使用,一般的應用不需要關心,應用的log都輸出到main緩沖區中。默認log輸出(不指定緩沖區的情況下)是輸出System和Main緩沖區的log。
4.7.1.7 打印指定日志緩沖區的大小
adb logcat -g
復制代碼
4.7.2 內核日志
adb shell dmesg
復制代碼
輸出示例:
<6>[14201.684016] PM: noirq resume of devices complete after 0.982 msecs
<6>[14201.685525] PM: early resume of devices complete after 0.838 msecs
<6>[14201.753642] PM: resume of devices complete after 68.106 msecs
<4>[14201.755954] Restarting tasks ... done.
<6>[14201.771229] PM: suspend exit 2016-08-28 13:31:32.679217193 UTC
<6>[14201.872373] PM: suspend entry 2016-08-28 13:31:32.780363596 UTC
<6>[14201.872498] PM: Syncing filesystems ... done.
復制代碼
中括號里的 [14201.684016]
代表內核開始啟動后的時間,單位為秒。
通過內核日志我們可以做一些事情,比如衡量內核啟動時間,在系統啟動完畢后的內核日志里找到 Freeing init memory
那一行前面的時間就是。
4.8 查看 Android 設備系統屬性
查看 Android 設備系統屬性的基本命令格式是:
adb shell getprop [options]
除了可以查看 Android 設備系統屬性之外,還可以設置系統屬性,設置系統屬性的基本命令格式是:
adb shell setprop <key> <value>
4.8.1 查看設備型號
adb shell getprop ro.product.model
輸出示例:
huawei mate 30 pro
復制代碼
4.8.2 查看設備電池狀況
adb shell dumpsys battery
輸出示例:
Current Battery Service state:
AC powered: false
USB powered: true
Wireless powered: false
status: 2
health: 2
present: true
level: 44
scale: 100
voltage: 3872
temperature: 280
technology: Li-poly
復制代碼
其中 scale
代表最大電量,level
代表當前電量。上面的輸出表示還剩下 44% 的電量。
4.8.3 查看設備屏幕分辨率
adb shell wm size
輸出示例:
Physical size: 1080x1920
該設備屏幕分辨率為 1080px * 1920px。
如果使用命令修改過,那輸出可能是:
Physical size: 1080x1920
Override size: 480x1024
復制代碼
表明設備的屏幕分辨率原本是 1080px * 1920px,當前被修改為 480px * 1024px。
4.8.4 查看設備屏幕密度
adb shell wm density
輸出示例:
Physical density: 360
該設備屏幕密度為 360dpi。
如果使用命令修改過,那輸出可能是:
Physical density: 420 Override density: 360
表明設備的屏幕密度原來是 420dpi,當前被修改為 360dpi。
4.8.5 查看設備顯示屏參數
adb shell dumpsys window displays
輸出示例:
WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)
Display: mDisplayId=0
init=1080x1920 420dpi cur=1080x1920 app=1080x1794 rng=1080x1017-1810x1731
deferred=false layoutNeeded=false
復制代碼
其中 mDisplayId
為 顯示屏編號,init
是初始分辨率和屏幕密度,app
的高度比 init
里的要小,表示屏幕底部有虛擬按鍵,高度為 1920 - 1794 = 126px 合 42dp。
4.8.6 查看設備 android_id
adb shell settings get secure android_id
輸出示例:
5a3a3aa2c3042184
4.8.7 查看設備IMEI
在 Android 4.4 及以下版本可通過如下命令獲取 IMEI:
adb shell dumpsys iphonesubinfo
輸出示例:
Phone Subscriber Info:
Phone Type = GSM
Device ID = 860955027785041
其中的 Device ID
就是 IMEI。
而在 Android 5.0 及以上版本里這個命令輸出為空,得通過其它方式獲取了(需要 root 權限):
adb shell
su
service call iphonesubinfo 1
把里面的有效內容提取出來就是 IMEI 了,比如這里的是 890956027785041
。
參考:adb shell dumpsys iphonesubinfo not working since Android 5.0 Lollipop
4.8.8 查看設備 Android 系統版本
adb shell getprop ro.build.version.release
輸出示例:
7.1.2
4.8.9 查看設備 IP 地址
adb shell ifconfig | grep Mask
在有的設備上這個命令沒有輸出,如果設備連着 WiFi,可以使用如下命令來查看局域網 IP:
adb shell ifconfig wlan0
如果以上命令仍然不能得到期望的信息,那可以試試以下命令(部分系統版本里可用):
adb shell netcfg
4.8.10 查看設備 Mac 地址
adb shell cat /sys/class/net/wlan0/address
輸出示例:
36:0f:a5:9a:c7:7d
這查看的是局域網 Mac 地址,移動網絡或其它連接的信息可以通過前面的小節「IP 地址」里提到的 adb shell netcfg
命令來查看。
4.8.11 查看設備 CPU 信息
adb shell cat /proc/cpuinfo
4.8.12 查看設備內存信息
adb shell cat /proc/meminfo
4.8.13 查看設備更多硬件與系統屬性
設備的更多硬件與系統屬性可以通過如下命令查看:
adb shell cat /system/build.prop
這會輸出很多信息,包括前面幾個小節提到的「型號」和「Android 系統版本」等。
輸出里還包括一些其它有用的信息,它們也可通過 adb shell getprop <屬性名>
命令單獨查看,列舉一部分屬性如下:
屬性名 | 含義 |
---|---|
ro.build.version.sdk | SDK 版本 |
ro.build.version.release | Android 系統版本 |
ro.build.version.security_patch | Android 安全補丁程序級別 |
ro.product.model | 型號 |
ro.product.brand | 品牌 |
ro.product.name | 設備名 |
ro.product.board | 處理器型號 |
ro.product.cpu.abilist | CPU 支持的 abi 列表[節注一] |
persist.sys.isUsbOtgEnabled | 是否支持 OTG |
dalvik.vm.heapsize | 每個應用程序的內存上限 |
ro.sf.lcd_density | 屏幕密度 |
節注一:
一些小廠定制的 ROM 可能修改過 CPU 支持的 abi 列表的屬性名,如果用 ro.product.cpu.abilist
屬性名查找不到,可以這樣試試:
adb shell cat /system/build.prop | grep ro.product.cpu.abi
示例輸出:
ro.product.cpu.abi=armeabi-v7a
ro.product.cpu.abi2=armeabi
4.9 修改設置
注: 修改設置之后,運行恢復命令有可能顯示仍然不太正常,可以運行 adb reboot
重啟設備,或手動重啟。
修改設置的原理主要是通過 settings 命令修改 /data/data/com.android.providers.settings/databases/settings.db 里存放的設置值。
4.9.1 修改分辨率
adb shell wm size 480x1024
表示將分辨率修改為 480px * 1024px。
恢復原分辨率命令:
adb shell wm size reset
4.9.2 修改屏幕密度
adb shell wm density 160
表示將屏幕密度修改為 160dpi。
恢復原屏幕密度命令:
adb shell wm density reset
4.9.3 修改顯示區域
adb shell wm overscan 0,0,0,200
四個數字分別表示距離左、上、右、下邊緣的留白像素,以上命令表示將屏幕底部 200px 留白。
恢復原顯示區域命令:
adb shell wm overscan reset
4.9.4 修改關閉 USB 調試模式
adb shell settings put global adb_enabled 0
用命令恢復不了了,畢竟關閉了 USB 調試 adb 就連接不上 Android 設備了。 去設備上手動恢復吧:「設置」-「開發者選項」-「Android 調試」。
4.9.5 修改允許/禁止訪問非 SDK API
允許訪問非 SDK API:
adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1
復制代碼
禁止訪問非 SDK API:
adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps
復制代碼
不需要設備獲得 Root 權限。
命令最后的數字的含義:
值 | 含義 |
---|---|
0 | 禁止檢測非 SDK 接口的調用。該情況下,日志記錄功能被禁用,並且令 strict mode API,即 detectNonSdkApiUsage() 無效。不推薦。 |
1 | 僅警告——允許訪問所有非 SDK 接口,但保留日志中的警告信息,可繼續使用 strick mode API。 |
2 | 禁止調用深灰名單和黑名單中的接口。 |
3 | 禁止調用黑名單中的接口,但允許調用深灰名單中的接口。 |
4.9.6 修改狀態欄和導航欄的顯示隱藏
adb shell settings put global policy_control <key-values>
<key-values>
可由如下幾種鍵及其對應的值組成,格式為 <key1>=<value1>:<key2>=<value2>
。
key | 含義 |
---|---|
immersive.full | 同時隱藏 |
immersive.status | 隱藏狀態欄 |
immersive.navigation | 隱藏導航欄 |
immersive.preconfirms | ? |
這些鍵對應的值可則如下值用逗號組合:
value | 含義 |
---|---|
apps |
所有應用 |
* |
所有界面 |
package-name |
指定應用 |
-package-name |
排除指定應用 |
例如:
adb shell settings put global policy_control immersive.full=*
表示設置在所有界面下都同時隱藏狀態欄和導航欄。
adb shell settings put global policy_control immersive.status=com.package1,com.package2:immersive.navigation=apps,-com.package3
表示設置在包名為 com.package1
和 com.package2
的應用里隱藏狀態欄,在除了包名為 com.package3
的所有應用里隱藏導航欄。
4.11 實用功能
4.11.1 屏幕截圖
截圖保存到電腦:
adb exec-out screencap -p > sc.png
如果 adb 版本較老,無法使用 exec-out
命令,這時候建議更新 adb 版本。無法更新的話可以使用以下麻煩點的辦法:
先截圖保存到設備里:
adb shell screencap -p /sdcard/sc.png
然后將 png 文件導出到電腦:
adb pull /sdcard/sc.png
可以使用 adb shell screencap -h
查看 screencap
命令的幫助信息,下面是兩個有意義的參數及含義:
參數 | 含義 |
---|---|
-p | 指定保存文件為 png 格式 |
-d display-id | 指定截圖的顯示屏編號(有多顯示屏的情況下) |
實測如果指定文件名以 .png
結尾時可以省略 -p 參數;否則需要使用 -p 參數。如果不指定文件名,截圖文件的內容將直接輸出到 stdout。
另外一種一行命令截圖並保存到電腦的方法: Linux 和 Windows
adb shell screencap -p | sed "s/\r$//" > sc.png
Mac OS X
adb shell screencap -p | gsed "s/\r$//" > sc.png
這個方法需要用到 gnu sed 命令,在 Linux 下直接就有,在 Windows 下 Git 安裝目錄的 bin 文件夾下也有。如果確實找不到該命令,可以下載 sed for Windows 並將 sed.exe 所在文件夾添加到 PATH 環境變量里。
而在 Mac 下使用系統自帶的 sed 命令會報錯:
sed: RE error: illegal byte sequence
需要安裝 gnu-sed,然后使用 gsed 命令:
brew install gnu-sed
4.11.2 錄制屏幕
錄制屏幕以 mp4 格式保存到 /sdcard:
adb shell screenrecord /sdcard/filename.mp4
需要停止時按 Ctrl-C,默認錄制時間和最長錄制時間都是 180 秒。
如果需要導出到電腦:
adb pull /sdcard/filename.mp4
可以使用 adb shell screenrecord --help
查看 screenrecord
命令的幫助信息,下面是常見參數及含義:
參數 | 含義 |
---|---|
--size WIDTHxHEIGHT | 視頻的尺寸,比如 1280x720 ,默認是屏幕分辨率。 |
--bit-rate RATE | 視頻的比特率,默認是 4Mbps。 |
--time-limit TIME | 錄制時長,單位秒。 |
--verbose | 輸出更多信息。 |
4.11.3 查看連接過的 WiFi 密碼
注:需要 root 權限。
adb shell su cat /data/misc/wifi/*.conf
4.11.4 設置系統日期和時間
注:需要 root 權限。
adb shell su date -s 20160823.131500
表示將系統日期和時間更改為 2016 年 08 月 23 日 13 點 15 分 00 秒。
4.11.5 重啟手機
adb reboot
4.11.6 檢測設備是否已 root
adb shell
su
此時命令行提示符是 $
則表示沒有 root 權限,是 #
則表示已 root。
4.11.7 使用 Monkey 進行壓力測試
Monkey 可以生成偽隨機用戶事件來模擬單擊、觸摸、手勢等操作,可以對正在開發中的程序進行隨機壓力測試。
簡單用法:
adb shell monkey -p <packagename> -v 500
表示向 <packagename>
指定的應用程序發送 500 個偽隨機事件。 Monkey 的詳細用法參考 官方文檔。
4.11.8 開啟/關閉 WiFi
注:需要 root 權限。
- 開啟 WiFi:
adb root
adb shell svc wifi enable
- 關閉 WiFi:
adb root
adb shell svc wifi disable
若執行成功,輸出為空;若未取得 root 權限執行此命令,將執行失敗,輸出 Killed
。
4.12 安全相關命令
4.12.1 啟用/禁用 SELinux
啟用 SELinux
adb root adb shell setenforce 1
禁用 SELinux
adb root adb shell setenforce 0
4.12.2 啟用/禁用 dm_verity
啟用 dm_verity
adb root
adb enable-verity
禁用 dm_verity
adb root
adb disable-verity
4.13 更多 adb shell 命令
Android 系統是基於 Linux 內核的,所以 Linux 里的很多命令在 Android 里也有相同或類似的實現,在 adb shell
里可以調用。本文檔前面的部分內容已經用到了 adb shell
命令。
4.14.1 查看進程狀態
adb shell ps
輸出信息各列含義:
列名 | 含義 |
---|---|
USER | 所屬用戶 |
PID | 進程 ID |
PPID | 父進程 ID |
NAME | 進程名 |
4.14.2 查看處理器實時狀態
adb shell top [-m max_procs] [-n iterations] [-d delay] [-s sort_column] [-t] [-h]
adb shell top
后面可以跟一些可選參數進行過濾查看不同的列表,可用參數及含義如下:
參數 | 含義 |
---|---|
-m | 最多顯示多少個進程 |
-n | 刷新多少次后退出 |
-d | 刷新時間間隔(單位秒,默認值5) |
-s | 按某列排序(可用col值:cpu, vss, rss, thr) |
-t | 顯示線程信息 |
-h | 顯示幫助文檔 |
輸出信息各列含義:
列名 | 含義 |
---|---|
PID | 進程 ID |
PR | 優先級 |
CPU% | 當前瞬間占用 CPU 百分比 |
S | 進程狀態(R=運行,S=睡眠,T=跟蹤/停止,Z=僵屍進程) |
#THR | 線程數 |
VSS | Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存) |
RSS | Resident Set Size 實際使用物理內存(包含共享庫占用的內存) |
PCY | 調度策略優先級,SP_BACKGROUND/SPFOREGROUND |
UID | 進程所有者的用戶 ID |
NAME | 進程名 |
4.14.3 查看進程 UID
有兩種方案:
方案一:
adb shell dumpsys package <packagename> | grep userId= 如: adb shell dumpsys package org.mazhuang.guanggoo | grep userId= userId=10394
方案二:
通過 ps 命令找到對應進程的 pid 之后 adb shell cat /proc/<pid>/status | grep Uid
如:
adb shell gemini:/ $ ps | grep org.mazhuang.guanggoo u0_a394 28635 770 1795812 78736 SyS_epoll_ 0000000000 S org.mazhuang.guanggoo gemini:/ $ cat /proc/28635/status | grep Uid Uid: 10394 10394 10394 10394 gemini:/ $