基本用法
基本命令
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 日誌)。