目錄
com.android.ddmlib.AdbCommandRejectedException
adb 命令的基本語法如下:
adb [-d|-e|-s <serialNumber>] <command>
如果只有一個設備/模擬器連接時,可以省略掉 [-d|-e|-s <serialNumber>]
這一部分,直接使用 adb <command>
。
如果有多個設備/模擬器連接,則需要為命令指定目標設備。
參數(shù) | 含義 |
---|---|
-d | 指定當前唯一通過 USB 連接的 Android 設備為命令目標 |
-e | 指定當前唯一運行的模擬器為命令目標 |
-s <serialNumber> | 指定相應 serialNumber 號的設備/模擬器為命令目標 |
在多個設備/模擬器連接的情況下較常用的是 -s <serialNumber>
參數(shù),serialNumber 可以通過 adb devices
命令獲取。如:
$ adb devicesList of devices attachedcf264b8f deviceemulator-5554 device10.129.164.6:5555 device
輸出里的 cf264b8f
、emulator-5554
和 10.129.164.6:5555
即為 serialNumber。
比如這時想指定 cf264b8f
這個設備來運行 adb 命令獲取屏幕分辨率:
adb -s cf264b8f shell wm size
又如想給 10.129.164.6:5555
這個設備安裝應用(這種形式的 serialNumber 格式為 <IP>:<Port>
,一般為無線連接的設備或 Genymotion 等第三方 Android 模擬器):
adb -s 10.129.164.6:5555 install test.apk
遇到多設備/模擬器的情況均使用這幾個參數(shù)為命令指定目標設備,下文中為簡化描述,不再重復。
啟動 adb server 命令:
adb start-server
(一般無需手動執(zhí)行此命令,在運行 adb 命令時若發(fā)現(xiàn) adb server 沒有啟動會自動調(diào)起。)
停止 adb server 命令:
adb kill-server
命令:
adb version
示例輸出:
Android Debug Bridge version 1.0.36Revision 8f855a3d9b35-android
adb 的運行原理是 PC 端的 adb server 與手機端的守護進程 adbd 建立連接,然后 PC 端的 adb client 通過 adb server 轉(zhuǎn)發(fā)命令,adbd 接收命令后解析運行。
所以如果 adbd 以普通權(quán)限執(zhí)行,有些需要 root 權(quán)限才能執(zhí)行的命令無法直接用 adb xxx
執(zhí)行。這時可以 adb shell
然后 su
后執(zhí)行命令,也可以讓 adbd 以 root 權(quán)限執(zhí)行,這個就能隨意執(zhí)行高權(quán)限命令了。
命令:
adb root
正常輸出:
restarting adbd as root
現(xiàn)在再運行 adb shell
,看看命令行提示符是不是變成 #
了?
有些手機 root 后也無法通過 adb root
命令讓 adbd 以 root 權(quán)限執(zhí)行,比如三星的部分機型,會提示 adbd cannot run as root in production builds
,此時可以先安裝 adbd Insecure,然后 adb root
試試。
相應地,如果要恢復 adbd 為非 root 權(quán)限的話,可以使用 adb unroot
命令。
命令:
adb -P <port> start-server
默認端口為 5037。
命令:
adb devices
輸出示例:
List of devices attachedcf264b8f deviceemulator-5554 device10.129.164.6:5555 device
輸出格式為 [serialNumber] [state]
,serialNumber 即我們常說的 SN,state 有如下幾種:
offline
—— 表示設備未連接成功或無響應。
device
—— 設備已連接。注意這個狀態(tài)并不能標識 Android 系統(tǒng)已經(jīng)完全啟動和可操作,在設備啟動過程中設備實例就可連接到 adb,但啟動完畢后系統(tǒng)才處于可操作狀態(tài)。
no device
—— 沒有設備/模擬器連接。
以上輸出顯示當前已經(jīng)連接了三臺設備/模擬器,cf264b8f
、emulator-5554
和 10.129.164.6:5555
分別是它們的 SN。從 emulator-5554
這個名字可以看出它是一個 Android 模擬器,而 10.129.164.6:5555
這種形為 <IP>:<Port>
的 serialNumber 一般是無線連接的設備或 Genymotion 等第三方 Android 模擬器。
常見異常輸出:
沒有設備/模擬器連接成功。
List of devices attached
設備/模擬器未連接到 adb 或無響應。
List of devices attachedcf264b8f offline
通過 USB 連接來正常使用 adb 需要保證幾點:
硬件狀態(tài)正常。
包括 Android 設備處于正常開機狀態(tài),USB 連接線和各種接口完好。
Android 設備的開發(fā)者選項和 USB 調(diào)試模式已開啟。
可以到「設置」-「開發(fā)者選項」-「Android 調(diào)試」查看。
如果在設置里找不到開發(fā)者選項,那需要通過一個彩蛋來讓它顯示出來:在「設置」-「關于手機」連續(xù)點擊「版本號」7 次。
設備驅(qū)動狀態(tài)正常。
這一點貌似在 Linux 和 Mac OS X 下不用操心,在 Windows 下有可能遇到需要安裝驅(qū)動的情況,確認這一點可以右鍵「計算機」-「屬性」,到「設備管理器」里查看相關設備上是否有黃色感嘆號或問號,如果沒有就說明驅(qū)動狀態(tài)已經(jīng)好了。否則可以下載一個手機助手類程序來安裝驅(qū)動先。
通過 USB 線連接好電腦和設備后確認狀態(tài)。
adb devices
如果能看到
xxxxxx device
說明連接成功。
除了可以通過 USB 連接設備與電腦來使用 adb,也可以通過無線連接——雖然連接過程中也有需要使用 USB 的步驟,但是連接成功之后你的設備就可以在一定范圍內(nèi)擺脫 USB 連接線的限制啦!
操作步驟:
將 Android 設備與要運行 adb 的電腦連接到同一個局域網(wǎng),比如連到同一個 WiFi。
將設備與電腦通過 USB 線連接。
應確保連接成功(可運行 adb devices
看是否能列出該設備)。
讓設備在 5555 端口監(jiān)聽 TCP/IP 連接:
adb tcpip 5555
斷開 USB 連接。
找到設備的 IP 地址。
一般能在「設置」-「關于手機」-「狀態(tài)信息」-「IP地址」找到,也可以使用下文里 查看設備信息 - IP 地址 一節(jié)里的方法用 adb 命令來查看。
通過 IP 地址連接設備。
adb connect <device-ip-address>
這里的 <device-ip-address>
就是上一步中找到的設備 IP 地址。
確認連接狀態(tài)。
adb devices
如果能看到
<device-ip-address>:5555 device
說明連接成功。
如果連接不了,請確認 Android 設備與電腦是連接到了同一個 WiFi,然后再次執(zhí)行 adb connect <device-ip-address>
那一步;
如果還是不行的話,通過 adb kill-server
重新啟動 adb 然后從頭再來一次試試。
斷開無線連接
命令:
adb disconnect <device-ip-address>
注:需要 root 權(quán)限。
上一節(jié)「無線連接(需要借助 USB 線)」是官方文檔里介紹的方法,需要借助于 USB 數(shù)據(jù)線來實現(xiàn)無線連接。
既然我們想要實現(xiàn)無線連接,那能不能所有步驟下來都是無線的呢?答案是能的。
在 Android 設備上安裝一個終端模擬器。
已經(jīng)安裝過的設備可以跳過此步。我使用的終端模擬器下載地址是:Terminal Emulator for Android Downloads
將 Android 設備與要運行 adb 的電腦連接到同一個局域網(wǎng),比如連到同一個 WiFi。
打開 Android 設備上的終端模擬器,在里面依次運行命令:
susetprop service.adb.tcp.port 5555
找到 Android 設備的 IP 地址。
一般能在「設置」-「關于手機」-「狀態(tài)信息」-「IP地址」找到,也可以使用下文里 查看設備信息 - IP 地址 一節(jié)里的方法用 adb 命令來查看。
在電腦上通過 adb 和 IP 地址連接 Android 設備。
adb connect <device-ip-address>
這里的 <device-ip-address>
就是上一步中找到的設備 IP 地址。
如果能看到 connected to <device-ip-address>:5555
這樣的輸出則表示連接成功。
節(jié)注一:
有的設備,比如小米 5S + MIUI 8.0 + Android 6.0.1 MXB48T,可能在第 5 步之前需要重啟 adbd 服務,在設備的終端模擬器上運行:
restart adbd
如果 restart 無效,嘗試以下命令:
stop adbdstart adbd
查看應用列表的基本命令格式是
adb shell pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]
即在 adb shell pm list packages
的基礎上可以加一些參數(shù)進行過濾查看不同的列表,支持的過濾參數(shù)如下:
參數(shù) | 顯示列表 |
---|---|
無 | 所有應用 |
-f | 顯示應用關聯(lián)的 apk 文件 |
-d | 只顯示 disabled 的應用 |
-e | 只顯示 enabled 的應用 |
-s | 只顯示系統(tǒng)應用 |
-3 | 只顯示第三方應用 |
-i | 顯示應用的 installer |
-u | 包含已卸載應用 |
<FILTER> | 包名包含 <FILTER> 字符串 |
所有應用
命令:
adb shell pm list packages
輸出示例:
package:com.android.smoketestpackage:com.example.android.livecubespackage:com.android.providers.telephonypackage:com.google.android.googlequicksearchboxpackage:com.android.providers.calendarpackage:com.android.providers.mediapackage:com.android.protipspackage:com.android.documentsuipackage:com.android.gallerypackage:com.android.externalstorage...// other packages here...
系統(tǒng)應用
命令:
adb shell pm list packages -s
第三方應用
命令:
adb shell pm list packages -3
包名包含某字符串的應用
比如要查看包名包含字符串 mazhuang
的應用列表,命令:
adb shell pm list packages mazhuang
當然也可以使用 grep 來過濾:
adb shell pm list packages | grep mazhuang
命令格式:
adb install [-lrtsdg] <path_to_apk>
參數(shù):
adb install
后面可以跟一些可選參數(shù)來控制安裝 APK 的行為,可用參數(shù)及含義如下:
參數(shù) | 含義 |
---|---|
-l | 將應用安裝到保護目錄 /mnt/asec |
-r | 允許覆蓋安裝 |
-t | 允許安裝 AndroidManifest.xml 里 application 指定 android:testOnly="true" 的應用 |
-s | 將應用安裝到 sdcard |
-d | 允許降級覆蓋安裝 |
-g | 授予所有運行時權(quán)限 |
運行命令后如果見到類似如下輸出(狀態(tài)為 Success
)代表安裝成功:
[100%] /data/local/tmp/1.apk pkg: /data/local/tmp/1.apkSuccess
上面是當前最新版 v1.0.36 的 adb 的輸出,會顯示 push apk 文件到手機的進度百分比。
使用舊版本 adb 的輸出則是這樣的:
12040 KB/s (22205609 bytes in 1.801s) pkg: /data/local/tmp/SogouInput_android_v8.3_sweb.apkSuccess
而如果狀態(tài)為 Failure
則表示安裝失敗,比如:
[100%] /data/local/tmp/map-20160831.apk pkg: /data/local/tmp/map-20160831.apkFailure [INSTALL_FAILED_ALREADY_EXISTS]
常見安裝失敗輸出代碼、含義及可能的解決辦法如下:
輸出 | 含義 | 解決辦法 |
---|---|---|
INSTALL_FAILED_ALREADY_EXISTS | 應用已經(jīng)存在,或卸載了但沒卸載干凈 | adb install 時使用 -r 參數(shù),或者先 adb uninstall <packagename> 再安裝 |
INSTALL_FAILED_INVALID_APK | 無效的 APK 文件 | |
INSTALL_FAILED_INVALID_URI | 無效的 APK 文件名 | 確保 APK 文件名里無中文 |
INSTALL_FAILED_INSUFFICIENT_STORAGE | 空間不足 | 清理空間 |
INSTALL_FAILED_DUPLICATE_PACKAGE | 已經(jīng)存在同名程序 | |
INSTALL_FAILED_NO_SHARED_USER | 請求的共享用戶不存在 | |
INSTALL_FAILED_UPDATE_INCOMPATIBLE | 以前安裝過同名應用,但卸載時數(shù)據(jù)沒有移除;或者已安裝該應用,但簽名不一致 | 先 adb uninstall <packagename> 再安裝 |
INSTALL_FAILED_SHARED_USER_INCOMPATIBLE | 請求的共享用戶存在但簽名不一致 | |
INSTALL_FAILED_MISSING_SHARED_LIBRARY | 安裝包使用了設備上不可用的共享庫 | |
INSTALL_FAILED_REPLACE_COULDNT_DELETE | 替換時無法刪除 | |
INSTALL_FAILED_DEXOPT | dex 優(yōu)化驗證失敗或空間不足 | |
INSTALL_FAILED_OLDER_SDK | 設備系統(tǒng)版本低于應用要求 | |
INSTALL_FAILED_CONFLICTING_PROVIDER | 設備里已經(jīng)存在與應用里同名的 content provider | |
INSTALL_FAILED_NEWER_SDK | 設備系統(tǒng)版本高于應用要求 | |
INSTALL_FAILED_TEST_ONLY | 應用是 test-only 的,但安裝時沒有指定 -t 參數(shù) | |
INSTALL_FAILED_CPU_ABI_INCOMPATIBLE | 包含不兼容設備 CPU 應用程序二進制接口的 native code | |
INSTALL_FAILED_MISSING_FEATURE | 應用使用了設備不可用的功能 | |
INSTALL_FAILED_CONTAINER_ERROR | 1. sdcard 訪問失敗; 2. 應用簽名與 ROM 簽名一致,被當作內(nèi)置應用。 | 1. 確認 sdcard 可用,或者安裝到內(nèi)置存儲; 2. 打包時不與 ROM 使用相同簽名。 |
INSTALL_FAILED_INVALID_INSTALL_LOCATION | 1. 不能安裝到指定位置; 2. 應用簽名與 ROM 簽名一致,被當作內(nèi)置應用。 | 1. 切換安裝位置,添加或刪除 -s 參數(shù);2. 打包時不與 ROM 使用相同簽名。 |
INSTALL_FAILED_MEDIA_UNAVAILABLE | 安裝位置不可用 | 一般為 sdcard,確認 sdcard 可用或安裝到內(nèi)置存儲 |
INSTALL_FAILED_VERIFICATION_TIMEOUT | 驗證安裝包超時 | |
INSTALL_FAILED_VERIFICATION_FAILURE | 驗證安裝包失敗 | |
INSTALL_FAILED_PACKAGE_CHANGED | 應用與調(diào)用程序期望的不一致 | |
INSTALL_FAILED_UID_CHANGED | 以前安裝過該應用,與本次分配的 UID 不一致 | 清除以前安裝過的殘留文件 |
INSTALL_FAILED_VERSION_DOWNGRADE | 已經(jīng)安裝了該應用更高版本 | 使用 -d 參數(shù) |
INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE | 已安裝 target SDK 支持運行時權(quán)限的同名應用,要安裝的版本不支持運行時權(quán)限 | |
INSTALL_PARSE_FAILED_NOT_APK | 指定路徑不是文件,或不是以 .apk 結(jié)尾 | |
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 文件時遇到結(jié)構(gòu)性錯誤 | |
INSTALL_PARSE_FAILED_MANIFEST_EMPTY | 在 manifest 文件里找不到找可操作標簽(instrumentation 或 application) | |
INSTALL_FAILED_INTERNAL_ERROR | 因系統(tǒng)問題安裝失敗 | |
INSTALL_FAILED_USER_RESTRICTED | 用戶被限制安裝應用 | |
INSTALL_FAILED_DUPLICATE_PERMISSION | 應用嘗試定義一個已經(jīng)存在的權(quán)限名稱 | |
INSTALL_FAILED_NO_MATCHING_ABIS | 應用包含設備的應用程序二進制接口不支持的 native code | |
INSTALL_CANCELED_BY_USER | 應用安裝需要在設備上確認,但未操作設備或點了取消 | 在設備上同意安裝 |
INSTALL_FAILED_ACWF_INCOMPATIBLE | 應用程序與設備不兼容 | |
does not contain AndroidManifest.xml | 無效的 APK 文件 | |
is not a valid zip file | 無效的 APK 文件 | |
Offline | 設備未連接成功 | 先將設備與 adb 連接成功 |
unauthorized | 設備未授權(quán)允許調(diào)試 | |
error: device not found | 沒有連接成功的設備 | 先將設備與 adb 連接成功 |
protocol failure | 設備已斷開連接 | 先將設備與 adb 連接成功 |
Unknown option: -s | Android 2.2 以下不支持安裝到 sdcard | 不使用 -s 參數(shù) |
No space left on device | 空間不足 | 清理空間 |
Permission denied ... sdcard ... | sdcard 不可用 | |
signatures do not match the previously installed version; ignoring! | 已安裝該應用且簽名不一致 | 先卸載設備上的該應用,再安裝 |
adb install
內(nèi)部原理簡介
adb install
實際是分三步完成:
push apk 文件到 /data/local/tmp。
調(diào)用 pm install 安裝。
刪除 /data/local/tmp 下的對應 apk 文件。
所以,必要的時候也可以根據(jù)這個步驟,手動分步執(zhí)行安裝過程。
命令:
adb uninstall [-k] <packagename>
<packagename>
表示應用的包名,-k
參數(shù)可選,表示卸載應用但保留數(shù)據(jù)和緩存目錄。
命令示例:
adb uninstall com.qihoo360.mobilesafe
表示卸載 360 手機衛(wèi)士。
命令:
adb shell pm clear <packagename>
<packagename>
表示應用名包,這條命令的效果相當于在設置里的應用信息界面點擊了「清除緩存」和「清除數(shù)據(jù)」。
命令示例:
adb shell pm clear com.qihoo360.mobilesafe
表示清除 360 手機衛(wèi)士的數(shù)據(jù)和緩存。
命令:
adb shell dumpsys activity activities | grep mFocusedActivity
輸出示例:
mFocusedActivity: ActivityRecord{8079d7e u0 com.cyanogenmod.trebuchet/com.android.launcher3.Launcher t42}
其中的 com.cyanogenmod.trebuchet/com.android.launcher3.Launcher
就是當前處于前臺的 Activity。
命令:
adb shell dumpsys activity services [<packagename>]
<packagename>
參數(shù)不是必須的,指定 <packagename>
表示查看與某個包名相關的 Services,不指定表示查看所有 Services。
<packagename>
不一定要給出完整的包名,比如運行 adb shell dumpsys activity services org.mazhuang
,那么包名 org.mazhuang.demo1
、org.mazhuang.demo2
和 org.mazhuang123
等相關的 Services 都會列出來。
命令:
adb shell dumpsys package <packagename>
輸出中包含很多信息,包括 Activity Resolver Table、Registered ContentProviders、包名、userId、安裝后的文件資源代碼等路徑、版本信息、權(quán)限信息和授予狀態(tài)、簽名版本信息等。
<packagename>
表示應用包名。
輸出示例:
Activity Resolver Table: Non-Data Actions: android.intent.action.MAIN: 5b4cba8 org.mazhuang.guanggoo/.SplashActivity filter 5ec9dcc Action: "android.intent.action.MAIN" Category: "android.intent.category.LAUNCHER" AutoVerify=falseRegistered ContentProviders: org.mazhuang.guanggoo/com.tencent.bugly.beta.utils.BuglyFileProvider: Provider{7a3c394 org.mazhuang.guanggoo/com.tencent.bugly.beta.utils.BuglyFileProvider}ContentProvider Authorities: [org.mazhuang.guanggoo.fileProvider]: Provider{7a3c394 org.mazhuang.guanggoo/com.tencent.bugly.beta.utils.BuglyFileProvider} applicationInfo=ApplicationInfo{7754242 org.mazhuang.guanggoo}Key Set Manager: [org.mazhuang.guanggoo] Signing KeySets: 501Packages: Package [org.mazhuang.guanggoo] (c1d7f): userId=10394 pkg=Package{55f714c org.mazhuang.guanggoo} codePath=/data/app/org.mazhuang.guanggoo-2 resourcePath=/data/app/org.mazhuang.guanggoo-2 legacyNativeLibraryDir=/data/app/org.mazhuang.guanggoo-2/lib primaryCpuAbi=null secondaryCpuAbi=null versionCode=74 minSdk=15 targetSdk=25 versionName=1.1.74 splits=[base] apkSigningVersion=2 applicationInfo=ApplicationInfo{7754242 org.mazhuang.guanggoo} flags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ] privateFlags=[ RESIZEABLE_ACTIVITIES ] dataDir=/data/user/0/org.mazhuang.guanggoo supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity] timeStamp=2017-10-22 23:50:53 firstInstallTime=2017-10-22 23:50:25 lastUpdateTime=2017-10-22 23:50:55 installerPackageName=com.miui.packageinstaller signatures=PackageSignatures{af09595 [53c7caa2]} installPermissionsFixed=true installStatus=1 pkgFlags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ] requested permissions: android.permission.READ_PHONE_STATE android.permission.INTERNET android.permission.ACCESS_NETWORK_STATE android.permission.ACCESS_WIFI_STATE android.permission.READ_LOGS android.permission.WRITE_EXTERNAL_STORAGE android.permission.READ_EXTERNAL_STORAGE install permissions: android.permission.INTERNET: granted=true android.permission.ACCESS_NETWORK_STATE: granted=true android.permission.ACCESS_WIFI_STATE: granted=true User 0: ceDataInode=1155675 installed=true hidden=false suspended=false stopped=true notLaunched=false enabled=0 gids=[3003] runtime permissions: android.permission.READ_EXTERNAL_STORAGE: granted=true android.permission.READ_PHONE_STATE: granted=true android.permission.WRITE_EXTERNAL_STORAGE: granted=true User 999: ceDataInode=0 installed=false hidden=false suspended=false stopped=true notLaunched=true enabled=0 gids=[3003] runtime permissions:Dexopt state: [org.mazhuang.guanggoo] Instruction Set: arm64 path: /data/app/org.mazhuang.guanggoo-2/base.apk status: /data/app/org.mazhuang.guanggoo-2/oat/arm64/base.odex [compilation_filter=speed-profile, status=kOatUpToDa te]
主要是使用 am <command>
命令,常用的 <command>
如下:
command | 用途 |
---|---|
start [options] <INTENT> | 啟動 <INTENT> 指定的 Activity |
startservice [options] <INTENT> | 啟動 <INTENT> 指定的 Service |
broadcast [options] <INTENT> | 發(fā)送 <INTENT> 指定的廣播 |
force-stop <packagename> | 停止 <packagename> 相關的進程 |
<INTENT>
參數(shù)很靈活,和寫 Android 程序時代碼里的 Intent 相對應。
用于決定 intent 對象的選項如下:
參數(shù) | 含義 |
---|---|
-a <ACTION> | 指定 action,比如 android.intent.action.VIEW |
-c <CATEGORY> | 指定 category,比如 android.intent.category.APP_CONTACTS |
-n <COMPONENT> | 指定完整 component 名,用于明確指定啟動哪個 Activity,如 com.example.app/.ExampleActivity |
<INTENT>
里還能帶數(shù)據(jù),就像寫代碼時的 Bundle 一樣:
參數(shù) | 含義 |
---|---|
--esn <EXTRA_KEY> | null 值(只有 key 名) |
`-e | --es <EXTRA_KEY> <EXTRA_STRING_VALUE>` |
--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 數(shù)組 |
--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...] | long 數(shù)組 |
命令格式:
adb shell am start [options] <INTENT>
例如:
adb shell am start -n com.tencent.mm/.ui.LauncherUI
表示調(diào)起微信主界面。
adb shell am start -n org.mazhuang.boottimemeasure/.MainActivity --es "toast" "hello, world"
表示調(diào)起 org.mazhuang.boottimemeasure/.MainActivity
并傳給它 string 數(shù)據(jù)鍵值對 toast - hello, world
。
命令格式:
adb shell am startservice [options] <INTENT>
例如:
adb shell am startservice -n com.tencent.mm/.plugin.accountsync.model.AccountAuthenticatorService
表示調(diào)起微信的某 Service。
命令格式:
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/.BootCompletedReceiver
這類用法在測試的時候很實用,比如某個廣播的場景很難制造,可以考慮通過這種方式來發(fā)送廣播。
既能發(fā)送系統(tǒng)預定義的廣播,也能發(fā)送自定義廣播。如下是部分系統(tǒng)預定義廣播及正常觸發(fā)時機:
action | 觸發(fā)時機 |
---|---|
android.net.conn.CONNECTIVITY_CHANGE | 網(wǎng)絡連接發(fā)生變化 |
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 連接狀態(tài)發(fā)生變化 |
android.net.wifi.WIFI_STATE_CHANGED | WiFi 狀態(tài)變?yōu)閱⒂?關閉/正在啟動/正在關閉/未知 |
android.intent.action.BATTERY_CHANGED | 電池電量發(fā)生變化 |
android.intent.action.INPUT_METHOD_CHANGED | 系統(tǒng)輸入法發(fā)生變化 |
android.intent.action.ACTION_POWER_CONNECTED | 外部電源連接 |
android.intent.action.ACTION_POWER_DISCONNECTED | 外部電源斷開連接 |
android.intent.action.DREAMING_STARTED | 系統(tǒng)開始休眠 |
android.intent.action.DREAMING_STOPPED | 系統(tǒng)停止休眠 |
android.intent.action.WALLPAPER_CHANGED | 壁紙發(fā)生變化 |
android.intent.action.HEADSET_PLUG | 插入耳機 |
android.intent.action.MEDIA_UNMOUNTED | 卸載外部介質(zhì) |
android.intent.action.MEDIA_MOUNTED | 掛載外部介質(zhì) |
android.os.action.POWER_SAVE_MODE_CHANGED | 省電模式開啟 |
(以上廣播均可使用 adb 觸發(fā))
命令:
adb shell am force-stop <packagename>
命令示例:
adb shell am force-stop com.qihoo360.mobilesafe
表示停止 360 安全衛(wèi)士的一切進程與服務。
命令:
adb pull <設備里的文件路徑> [電腦上的目錄]
其中 電腦上的目錄
參數(shù)可以省略,默認復制到當前目錄。
例:
adb pull /sdcard/sr.mp4 ~/tmp/
*小技巧:*設備上的文件路徑可能需要 root 權(quán)限才能訪問,如果你的設備已經(jīng) root 過,可以先使用 adb shell
和 su
命令在 adb shell 里獲取 root 權(quán)限后,先 cp /path/on/device /sdcard/filename
將文件復制到 sdcard,然后 adb pull /sdcard/filename /path/on/pc
。
命令:
adb push <電腦上的文件路徑> <設備里的目錄>
例:
adb push ~/sr.mp4 /sdcard/
*小技巧:*設備上的文件路徑普通權(quán)限可能無法直接寫入,如果你的設備已經(jīng) root 過,可以先 adb push /path/on/pc /sdcard/filename
,然后 adb shell
和 su
在 adb shell 里獲取 root 權(quán)限后,cp /sdcard/filename /path/on/device
。
在 adb shell
里有個很實用的命令叫 input
,通過它可以做一些有趣的事情。
input
命令的完整 help 信息如下:
Usage: input [<source>] <command> [<arg>...]The sources are: mouse keyboard joystick touchnavigation touchpad trackball stylus dpad gesture touchscreen gamepadThe 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 能實現(xiàn)不同的功能,完整的 keycode 列表詳見 KeyEvent,摘引部分我覺得有意思的如下:
keycode | 含義 |
---|---|
3 | HOME 鍵 |
4 | 返回鍵 |
5 | 打開撥號應用 |
6 | 掛斷電話 |
24 | 增加音量 |
25 | 降低音量 |
26 | 電源鍵 |
27 | 拍照(需要在相機應用里) |
64 | 打開瀏覽器 |
82 | 菜單鍵 |
85 | 播放/暫停 |
86 | 停止播放 |
87 | 播放下一首 |
88 | 播放上一首 |
122 | 移動光標到行首或列表頂部 |
123 | 移動光標到行末或列表底部 |
126 | 恢復播放 |
127 | 暫停播放 |
164 | 靜音 |
176 | 打開系統(tǒng)設置 |
187 | 切換應用 |
207 | 打開聯(lián)系人 |
208 | 打開日歷 |
209 | 打開音樂 |
210 | 打開計算器 |
220 | 降低屏幕亮度 |
221 | 提高屏幕亮度 |
223 | 系統(tǒng)休眠 |
224 | 點亮屏幕 |
231 | 打開語音助手 |
276 | 如果沒有 wakelock 則讓系統(tǒng)休眠 |
下面是 input
命令的一些用法舉例。
命令:
adb shell input keyevent 26
執(zhí)行效果相當于按電源鍵。
命令:
adb shell input keyevent 82
命令:
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
來解鎖。
命令(參數(shù)以機型 Nexus 5,向上滑動手勢解鎖舉例):
adb shell input swipe 300 1000 300 500
參數(shù) 300 1000 300 500
分別表示起始點x坐標 起始點y坐標 結(jié)束點x坐標 結(jié)束點y坐標
。
在焦點處于某文本框時,可以通過 input
命令來輸入文本。
命令:
adb shell input text hello
現(xiàn)在 hello
出現(xiàn)在文本框了。
Android 系統(tǒng)的日志分為兩部分,底層的 Linux 內(nèi)核日志輸出到 /proc/kmsg,Android 的日志輸出到 /dev/log。
命令格式:
[adb] logcat [<option>] ... [<filter-spec>] ...
常用用法列舉如下:
按級別過濾日志
Android 的日志分為如下幾個優(yōu)先級(priority):
按某級別過濾日志則會將該級別及以上的日志輸出。
比如,命令:
adb logcat *:W
會將 Warning、Error、Fatal 和 Silent 日志輸出。
(注: 在 macOS 下需要給 *:W
這樣以 *
作為 tag 的參數(shù)加雙引號,如 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 日志)。
日志格式
可以用 adb logcat -v <format>
選項指定日志輸出格式。
日志支持按以下幾種 <format>
:
brief
默認格式。格式為:
<priority>/<tag>(<pid>): <message>
示例:
D/HeadsetStateMachine( 1785): Disconnected process message: 10, size: 0
process
格式為:
<priority>(<pid>) <message>
示例:
D( 1785) Disconnected process message: 10, size: 0 (HeadsetStateMachine)
tag
格式為:
<priority>/<tag>: <message>
示例:
D/HeadsetStateMachine: Disconnected process message: 10, size: 0
raw
格式為:
<message>
示例:
Disconnected process message: 10, size: 0
time
格式為:
<datetime> <priority>/<tag>(<pid>): <message>
示例:
08-28 22:39:39.974 D/HeadsetStateMachine( 1785): Disconnected process message: 10, size: 0
threadtime
格式為:
<datetime> <pid> <tid> <priority> <tag>: <message>
示例:
08-28 22:39:39.974 1785 1832 D HeadsetStateMachine: Disconnected process message: 10, size: 0
long
格式為:
[ <datetime> <pid>:<tid> <priority>/<tag> ]<message>
示例:
[ 08-28 22:39:39.974 1785: 1832 D/HeadsetStateMachine ]Disconnected process message: 10, size: 0
指定格式可與上面的過濾同時使用。比如:
adb logcat -v long ActivityManager:I *:S
清空日志
adb logcat -c
命令:
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]
代表內(nèi)核開始啟動后的時間,單位為秒。
通過內(nèi)核日志我們可以做一些事情,比如衡量內(nèi)核啟動時間,在系統(tǒng)啟動完畢后的內(nèi)核日志里找到 Freeing init memory
那一行前面的時間就是。
命令:
adb shell getprop ro.product.model
輸出示例:
Nexus 5
命令:
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% 的電量。
命令:
adb shell wm size
輸出示例:
Physical size: 1080x1920
該設備屏幕分辨率為 1080px * 1920px。
如果使用命令修改過,那輸出可能是:
Physical size: 1080x1920Override size: 480x1024
表明設備的屏幕分辨率原本是 1080px * 1920px,當前被修改為 480px * 1024px。
命令:
adb shell wm density
輸出示例:
Physical density: 420
該設備屏幕密度為 420dpi。
如果使用命令修改過,那輸出可能是:
Physical density: 480Override density: 160
表明設備的屏幕密度原來是 480dpi,當前被修改為 160dpi。
命令:
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。
命令:
adb shell settings get secure android_id
輸出示例:
51b6be48bac8c569
在 Android 4.4 及以下版本可通過如下命令獲取 IMEI:
adb shell dumpsys iphonesubinfo
輸出示例:
Phone Subscriber Info: Phone Type = GSM Device ID = 860955027785041
其中的 Device ID
就是 IMEI。
而在 Android 5.0 及以上版本里這個命令輸出為空,得通過其它方式獲取了(需要 root 權(quán)限):
adb shellsuservice call iphonesubinfo 1
輸出示例:
Result: Parcel( 0x00000000: 00000000 0000000f 00360038 00390030 '........8.6.0.9.' 0x00000010: 00350035 00320030 00370037 00350038 '5.5.0.2.7.7.8.5.' 0x00000020: 00340030 00000031 '0.4.1... ')
把里面的有效內(nèi)容提取出來就是 IMEI 了,比如這里的是 860955027785041
。
參考:adb shell dumpsys iphonesubinfo not working since Android 5.0 Lollipop
命令:
adb shell getprop ro.build.version.release
輸出示例:
5.0.2
每次想知道設備的 IP 地址的時候都得「設置」-「關于手機」-「狀態(tài)信息」-「IP地址」很煩對不對?通過 adb 可以方便地查看。
命令:
adb shell ifconfig | grep Mask
輸出示例:
inet addr:10.130.245.230 Mask:255.255.255.252inet addr:127.0.0.1 Mask:255.0.0.0
那么 10.130.245.230
就是設備 IP 地址。
在有的設備上這個命令沒有輸出,如果設備連著 WiFi,可以使用如下命令來查看局域網(wǎng) IP:
adb shell ifconfig wlan0
輸出示例:
wlan0: ip 10.129.160.99 mask 255.255.240.0 flags [up broadcast running multicast]
或
wlan0 Link encap:UNSPEC inet addr:10.129.168.57 Bcast:10.129.175.255 Mask:255.255.240.0 inet6 addr: fe80::66cc:2eff:fe68:b6b6/64 Scope: Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:496520 errors:0 dropped:0 overruns:0 frame:0 TX packets:68215 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3000 RX bytes:116266821 TX bytes:8311736
如果以上命令仍然不能得到期望的信息,那可以試試以下命令(部分系統(tǒng)版本里可用):
adb shell netcfg
輸出示例:
wlan0 UP 10.129.160.99/20 0x00001043 f8:a9:d0:17:42:4dlo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00p2p0 UP 0.0.0.0/0 0x00001003 fa:a9:d0:17:42:4dsit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00rmnet0 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00rmnet1 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00rmnet3 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00rmnet2 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00rmnet4 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00rmnet6 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00rmnet5 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00rmnet7 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00rev_rmnet3 DOWN 0.0.0.0/0 0x00001002 4e:b7:e4:2e:17:58rev_rmnet2 DOWN 0.0.0.0/0 0x00001002 4e:f0:c8:bf:7a:cfrev_rmnet4 DOWN 0.0.0.0/0 0x00001002 a6:c0:3b:6b:c4:1frev_rmnet6 DOWN 0.0.0.0/0 0x00001002 66:bb:5d:64:2e:e9rev_rmnet5 DOWN 0.0.0.0/0 0x00001002 0e:1b:eb:b9:23:a0rev_rmnet7 DOWN 0.0.0.0/0 0x00001002 7a:d9:f6:81:40:5arev_rmnet8 DOWN 0.0.0.0/0 0x00001002 4e:e2:a9:bb:d0:1brev_rmnet0 DOWN 0.0.0.0/0 0x00001002 fe:65:d0:ca:82:a9rev_rmnet1 DOWN 0.0.0.0/0 0x00001002 da:d8:e8:4f:2e:fe
可以看到網(wǎng)絡連接名稱、啟用狀態(tài)、IP 地址和 Mac 地址等信息。
命令:
adb shell cat /sys/class/net/wlan0/address
輸出示例:
f8:a9:d0:17:42:4d
這查看的是局域網(wǎng) Mac 地址,移動網(wǎng)絡或其它連接的信息可以通過前面的小節(jié)「IP 地址」里提到的 adb shell netcfg
命令來查看。
命令:
adb shell cat /proc/cpuinfo
輸出示例:
Processor : ARMv7 Processor rev 0 (v7l)processor : 0BogoMIPS : 38.40processor : 1BogoMIPS : 38.40processor : 2BogoMIPS : 38.40processor : 3BogoMIPS : 38.40Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivtCPU implementer : 0x51CPU architecture: 7CPU variant : 0x2CPU part : 0x06fCPU revision : 0Hardware : Qualcomm MSM 8974 HAMMERHEAD (Flattened Device Tree)Revision : 000bSerial : 0000000000000000
這是 Nexus 5 的 CPU 信息,我們從輸出里可以看到使用的硬件是 Qualcomm MSM 8974
,processor 的編號是 0 到 3,所以它是四核的,采用的架構(gòu)是 ARMv7 Processor rev 0 (v71)
。
命令:
adb shell cat /proc/meminfo
輸出示例:
MemTotal: 1027424 kBMemFree: 486564 kBBuffers: 15224 kBCached: 72464 kBSwapCached: 24152 kBActive: 110572 kBInactive: 259060 kBActive(anon): 79176 kBInactive(anon): 207736 kBActive(file): 31396 kBInactive(file): 51324 kBUnevictable: 3948 kBMlocked: 0 kBHighTotal: 409600 kBHighFree: 132612 kBLowTotal: 617824 kBLowFree: 353952 kBSwapTotal: 262140 kBSwapFree: 207572 kBDirty: 0 kBWriteback: 0 kBAnonPages: 265324 kBMapped: 47072 kBShmem: 1020 kBSlab: 57372 kBSReclaimable: 7692 kBSUnreclaim: 49680 kBKernelStack: 4512 kBPageTables: 5912 kBNFS_Unstable: 0 kBBounce: 0 kBWritebackTmp: 0 kBCommitLimit: 775852 kBCommitted_AS: 13520632 kBVmallocTotal: 385024 kBVmallocUsed: 61004 kBVmallocChunk: 209668 kB
其中,MemTotal
就是設備的總內(nèi)存,MemFree
是當前空閑內(nèi)存。
設備的更多硬件與系統(tǒng)屬性可以通過如下命令查看:
adb shell cat /system/build.prop
這會輸出很多信息,包括前面幾個小節(jié)提到的「型號」和「Android 系統(tǒng)版本」等。
輸出里還包括一些其它有用的信息,它們也可通過 adb shell getprop <屬性名>
命令單獨查看,列舉一部分屬性如下:
屬性名 | 含義 |
---|---|
ro.build.version.sdk | SDK 版本 |
ro.build.version.release | Android 系統(tǒng)版本 |
ro.build.version.security_patch | Android 安全補丁程序級別 |
ro.product.model | 型號 |
ro.product.brand | 品牌 |
ro.product.name | 設備名 |
ro.product.board | 處理器型號 |
ro.product.cpu.abilist | CPU 支持的 abi 列表[節(jié)注一] |
persist.sys.isUsbOtgEnabled | 是否支持 OTG |
dalvik.vm.heapsize | 每個應用程序的內(nèi)存上限 |
ro.sf.lcd_density | 屏幕密度 |
節(jié)注一:
一些小廠定制的 ROM 可能修改過 CPU 支持的 abi 列表的屬性名,如果用 ro.product.cpu.abilist
屬性名查找不到,可以這樣試試:
adb shell cat /system/build.prop | grep ro.product.cpu.abi
示例輸出:
ro.product.cpu.abi=armeabi-v7aro.product.cpu.abi2=armeabi
注: 修改設置之后,運行恢復命令有可能顯示仍然不太正常,可以運行 adb reboot
重啟設備,或手動重啟。
修改設置的原理主要是通過 settings 命令修改 /data/data/com.android.providers.settings/databases/settings.db 里存放的設置值。
命令:
adb shell wm size 480x1024
表示將分辨率修改為 480px * 1024px。
恢復原分辨率命令:
adb shell wm size reset
命令:
adb shell wm density 160
表示將屏幕密度修改為 160dpi。
恢復原屏幕密度命令:
adb shell wm density reset
命令:
adb shell wm overscan 0,0,0,200
四個數(shù)字分別表示距離左、上、右、下邊緣的留白像素,以上命令表示將屏幕底部 200px 留白。
恢復原顯示區(qū)域命令:
adb shell wm overscan reset
命令:
adb shell settings put global adb_enabled 0
恢復:
用命令恢復不了了,畢竟關閉了 USB 調(diào)試 adb 就連接不上 Android 設備了。
去設備上手動恢復吧:「設置」-「開發(fā)者選項」-「Android 調(diào)試」。
本節(jié)所說的相關設置對應 Cyanogenmod 里的「擴展桌面」。
命令:
adb shell settings put global policy_control <key-values>
<key-values>
可由如下幾種鍵及其對應的值組成,格式為 <key1>=<value1>:<key2>=<value2>
。
key | 含義 |
---|---|
immersive.full | 同時隱藏 |
immersive.status | 隱藏狀態(tài)欄 |
immersive.navigation | 隱藏導航欄 |
immersive.preconfirms | ? |
這些鍵對應的值可則如下值用逗號組合:
value | 含義 |
---|---|
apps | 所有應用 |
* | 所有界面 |
packagename | 指定應用 |
-packagename | 排除指定應用 |
例如:
adb shell settings put global policy_control immersive.full=*
表示設置在所有界面下都同時隱藏狀態(tài)欄和導航欄。
adb shell settings put global policy_control immersive.status=com.package1,com.package2:immersive.navigation=apps,-com.package3
表示設置在包名為 com.package1
和 com.package2
的應用里隱藏狀態(tài)欄,在除了包名為 com.package3
的所有應用里隱藏導航欄。
截圖保存到電腦:
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
命令的幫助信息,下面是兩個有意義的參數(shù)及含義:
參數(shù) | 含義 |
---|---|
-p | 指定保存文件為 png 格式 |
-d display-id | 指定截圖的顯示屏編號(有多顯示屏的情況下) |
實測如果指定文件名以 .png
結(jié)尾時可以省略 -p 參數(shù);否則需要使用 -p 參數(shù)。如果不指定文件名,截圖文件的內(nèi)容將直接輸出到 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 環(huán)境變量里。
而在 Mac 下使用系統(tǒng)自帶的 sed 命令會報錯:
sed: RE error: illegal byte sequence
需要安裝 gnu-sed,然后使用 gsed 命令:
brew install gnu-sed
錄制屏幕以 mp4 格式保存到 /sdcard:
adb shell screenrecord /sdcard/filename.mp4
需要停止時按 Ctrl-C,默認錄制時間和最長錄制時間都是 180 秒。
如果需要導出到電腦:
adb pull /sdcard/filename.mp4
可以使用 adb shell screenrecord --help
查看 screenrecord
命令的幫助信息,下面是常見參數(shù)及含義:
參數(shù) | 含義 |
---|---|
--size WIDTHxHEIGHT | 視頻的尺寸,比如 1280x720 ,默認是屏幕分辨率。 |
--bit-rate RATE | 視頻的比特率,默認是 4Mbps。 |
--time-limit TIME | 錄制時長,單位秒。 |
--verbose | 輸出更多信息。 |
注:需要 root 權(quán)限。
/system 分區(qū)默認掛載為只讀,但有些操作比如給 Android 系統(tǒng)添加命令、刪除自帶應用等需要對 /system 進行寫操作,所以需要重新掛載它為可讀寫。
步驟:
進入 shell 并切換到 root 用戶權(quán)限。
命令:
adb shellsu
查看當前分區(qū)掛載情況。
命令:
mount
輸出示例:
rootfs / rootfs ro,relatime 0 0tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,mode=755 0 0devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0proc /proc proc rw,relatime 0 0sysfs /sys sysfs rw,seclabel,relatime 0 0selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0debugfs /sys/kernel/debug debugfs rw,relatime 0 0none /var tmpfs rw,seclabel,relatime,mode=770,gid=1000 0 0none /acct cgroup rw,relatime,cpuacct 0 0none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0none /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0tmpfs /mnt/asec tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0tmpfs /mnt/obb tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0none /dev/memcg cgroup rw,relatime,memory 0 0none /dev/cpuctl cgroup rw,relatime,cpu 0 0none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0none /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0none /sys/fs/cgroup/freezer cgroup rw,relatime,freezer 0 0/dev/block/platform/msm_sdcc.1/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0/dev/block/platform/msm_sdcc.1/by-name/userdata /data ext4 rw,seclabel,nosuid,nodev,relatime,noauto_da_alloc,data=ordered 0 0/dev/block/platform/msm_sdcc.1/by-name/cache /cache ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0/dev/block/platform/msm_sdcc.1/by-name/persist /persist ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0/dev/block/platform/msm_sdcc.1/by-name/modem /firmware vfat ro,context=u:object_r:firmware_file:s0,relatime,uid=1000,gid=1000,fmask=0337,dmask=0227,codepage=cp437,iocharset=iso8859-1,shortname=lower,errors=remount-ro 0 0/dev/fuse /mnt/shell/emulated fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0/dev/fuse /mnt/shell/emulated/0 fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
找到其中我們關注的帶 /system 的那一行:
/dev/block/platform/msm_sdcc.1/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0
重新掛載。
命令:
mount -o remount,rw -t yaffs2 /dev/block/platform/msm_sdcc.1/by-name/system /system
這里的 /dev/block/platform/msm_sdcc.1/by-name/system
就是我們從上一步的輸出里得到的文件路徑。
如果輸出沒有提示錯誤的話,操作就成功了,可以對 /system 下的文件為所欲為了。
注:需要 root 權(quán)限。
命令:
adb shellsucat /data/misc/wifi/*.conf
輸出示例:
network={ ssid="TP-LINK_9DFC" scan_ssid=1 psk="123456789" key_mgmt=WPA-PSK group=CCMP TKIP auth_alg=OPEN sim_num=1 priority=13893}network={ ssid="TP-LINK_F11E" psk="987654321" key_mgmt=WPA-PSK sim_num=1 priority=17293}
ssid
即為我們在 WLAN 設置里看到的名稱,psk
為密碼,key_mgmt
為安全加密方式。
注:需要 root 權(quán)限。
命令:
adb shellsudate -s 20160823.131500
表示將系統(tǒng)日期和時間更改為 2016 年 08 月 23 日 13 點 15 分 00 秒。
命令:
adb reboot
命令:
adb shellsu
此時命令行提示符是 $
則表示沒有 root 權(quán)限,是 #
則表示已 root。
Monkey 可以生成偽隨機用戶事件來模擬單擊、觸摸、手勢等操作,可以對正在開發(fā)中的程序進行隨機壓力測試。
簡單用法:
adb shell monkey -p <packagename> -v 500
表示向 <packagename>
指定的應用程序發(fā)送 500 個偽隨機事件。
Monkey 的詳細用法參考 官方文檔。
注:需要 root 權(quán)限。
有時需要控制設備的 WiFi 狀態(tài),可以用以下指令完成。
開啟 WiFi:
adb rootadb shell svc wifi enable
關閉 WiFi:
adb rootadb shell svc wifi disable
若執(zhí)行成功,輸出為空;若未取得 root 權(quán)限執(zhí)行此命令,將執(zhí)行失敗,輸出 Killed
。
命令:
adb reboot recovery
命令:
adb reboot
命令:
adb reboot bootloader
如果我們下載了 Android 設備對應的系統(tǒng)更新包到電腦上,那么也可以通過 adb 來完成更新。
以 Recovery 模式下更新為例:
重啟到 Recovery 模式。
命令:
adb reboot recovery
在設備的 Recovery 界面上操作進入 Apply update
-Apply from ADB
。
注:不同的 Recovery 菜單可能與此有差異,有的是一級菜單就有 Apply update from ADB
。
通過 adb 上傳和更新系統(tǒng)。
命令:
adb sideload <path-to-update.zip>
啟用 SELinux
adb rootadb shell setenforce 1
禁用 SELinux
adb rootadb shell setenforce 0
啟用 dm_verity
adb rootadb enable-verity
禁用 dm_verity
adb rootadb disable-verity
Android 系統(tǒng)是基于 Linux 內(nèi)核的,所以 Linux 里的很多命令在 Android 里也有相同或類似的實現(xiàn),在 adb shell
里可以調(diào)用。本文檔前面的部分內(nèi)容已經(jīng)用到了 adb shell
命令。
命令:
adb shell ps
輸出示例:
USER PID PPID VSIZE RSS WCHAN PC NAMEroot 1 0 8904 788 ffffffff 00000000 S /initroot 2 0 0 0 ffffffff 00000000 S kthreadd...u0_a71 7779 5926 1538748 48896 ffffffff 00000000 S com.sohu.inputmethod.sogou:classicu0_a58 7963 5926 1561916 59568 ffffffff 00000000 S org.mazhuang.boottimemeasure...shell 8750 217 10640 740 00000000 b6f28340 R ps
各列含義:
列名 | 含義 |
---|---|
USER | 所屬用戶 |
PID | 進程 ID |
PPID | 父進程 ID |
NAME | 進程名 |
命令:
adb shell top
輸出示例:
User 0%, System 6%, IOW 0%, IRQ 0%User 3 + Nice 0 + Sys 21 + Idle 280 + IOW 0 + IRQ 0 + SIRQ 3 = 307 PID PR CPU% S #THR VSS RSS PCY UID Name 8763 0 3% R 1 10640K 1064K fg shell top 131 0 3% S 1 0K 0K fg root dhd_dpc 6144 0 0% S 115 1682004K 115916K fg system system_server 132 0 0% S 1 0K 0K fg root dhd_rxf 1731 0 0% S 6 20288K 788K fg root /system/bin/mpdecision 217 0 0% S 6 18008K 356K fg shell /sbin/adbd ... 7779 2 0% S 19 1538748K 48896K bg u0_a71 com.sohu.inputmethod.sogou:classic 7963 0 0% S 18 1561916K 59568K fg u0_a58 org.mazhuang.boottimemeasure ...
各列含義:
列名 | 含義 |
---|---|
PID | 進程 ID |
PR | 優(yōu)先級 |
CPU% | 當前瞬間占用 CPU 百分比 |
S | 進程狀態(tài)(R=運行,S=睡眠,T=跟蹤/停止,Z=僵尸進程) |
#THR | 線程數(shù) |
VSS | Virtual Set Size 虛擬耗用內(nèi)存(包含共享庫占用的內(nèi)存) |
RSS | Resident Set Size 實際使用物理內(nèi)存(包含共享庫占用的內(nèi)存) |
PCY | 調(diào)度策略優(yōu)先級,SP_BACKGROUND/SPFOREGROUND |
UID | 進程所有者的用戶 ID |
NAME | 進程名 |
top
命令還支持一些命令行參數(shù),詳細用法如下:
Usage: top [ -m max_procs ] [ -n iterations ] [ -d delay ] [ -s sort_column ] [ -t ] [ -h ] -m num 最多顯示多少個進程 -n num 刷新多少次后退出 -d num 刷新時間間隔(單位秒,默認值 5) -s col 按某列排序(可用 col 值:cpu, vss, rss, thr) -t 顯示線程信息 -h 顯示幫助文檔
有兩種方案:
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 shellgemini:/ $ ps | grep org.mazhuang.guanggoou0_a394 28635 770 1795812 78736 SyS_epoll_ 0000000000 S org.mazhuang.guanggoogemini:/ $ cat /proc/28635/status | grep UidUid: 10394 10394 10394 10394gemini:/ $
如下是其它常用命令的簡單描述,前文已經(jīng)專門講過的命令不再額外說明:
命令 | 功能 |
---|---|
cat | 顯示文件內(nèi)容 |
cd | 切換目錄 |
chmod | 改變文件的存取模式/訪問權(quán)限 |
df | 查看磁盤空間使用情況 |
grep | 過濾輸出 |
kill | 殺死指定 PID 的進程 |
ls | 列舉目錄內(nèi)容 |
mount | 掛載目錄的查看和管理 |
mv | 移動或重命名文件 |
ps | 查看正在運行的進程 |
rm | 刪除文件 |
top | 查看進程的資源占用情況 |
出錯提示
error: protocol fault (couldn't read status): No error
可能原因
adb server 進程想使用的 5037 端口被占用。
解決方案
找到占用 5037 端口的進程,然后終止它。以 Windows 下為例:
netstat -ano | findstr LISTENING...TCP 0.0.0.0:5037 0.0.0.0:0 LISTENING 1548...
這里 1548 即為進程 ID,用命令結(jié)束該進程:
taskkill /PID 1548
然后再啟動 adb 就沒問題了。
在 Android Studio 里新建一個模擬器,但是用 adb 一直連接不上,提示:
com.android.ddmlib.AdbCommandRejectedException: device unauthorized.This adb server's $ADB_VENDOR_KEYS is not setTry 'adb kill-server' if that seems wrong.Otherwise check for a confirmation dialog on your device.
在手機上安裝一個終端然后執(zhí)行 su 提示沒有該命令,這不正常。
于是刪除該模擬器后重新下載安裝一次,這次就正常了。
ADB 的安裝這里就不多說了,輸入以下命令有如下提示就證明你環(huán)境ok,否則自行網(wǎng)上搜索解決下。
$ adb version
Android Debug Bridge version 1.0.36
Revision 8f855a3d9b35-android
輸入以下命令可以查詢已連接的設備與模擬器:
$ adb devices
List of devices attached
02ae0c1021089daf device
adb install <apkfile>
// 如: adb install demo.apk
如果不是當前目錄,則后面要跟路徑名:
adb install /Users/storm/temp/demo.apk
保留數(shù)據(jù)和緩存文件,重新安裝apk:
adb install -r demo.apk
安裝apk到sd卡:
adb install -s demo.apk
卸載
adb uninstall <package>
// 如:adb uninstall com.stormzhang.demo
卸載 app 但保留數(shù)據(jù)和緩存文件:
adb uninstall -k com.stormzhang.demo
一般來說,下面兩個命令基本不會用到,因為只要設備連接正確,會自動啟動 adb server 的,不過大家也需要知道這倆命令:
adb start-server
adb kill-server
adb shell pm list packages
adb shell pm list packages -s
adb shell pm list packages -3
adb shell pm list packages | grep qq
有些時候我們測試需要清除數(shù)據(jù)與緩存,則需要用到如下命令:
adb shell pm clear <packagename>
// 如:adb shell pm clear com.stormzhang.demo
如果我們想要通過 adb 來啟動應用
adb shell am start -n com.stormzhang.demo/.ui.SplashActivity
有些時候應用卡死了,需要強制停止,則執(zhí)行以下命令:
adb shell am force-stop <packagename>
// 如:adb shell am force-stop cn.androidstar.demo
adb logcat
adb reboot
$adb get-serialno
02ae0c1021089daf
$adb shell cat /sys/class/net/wlan0/address
bc:f5:ac:f9:f7:c8
$adb shell getprop ro.product.model
Nexus 5
$adb shell getprop ro.build.version.release
7.0.1
$adb shell wm size
Physical size: 1080×1920
$adb shell wm density
Physical density: 480
關于 ADB 的命令有太多,以上只列了一些我比較常用的命令,關于更多的命令可以見這里:
https://github.com/mzlogin/awesome-adb
ADB IDEA
以上命令你們覺得是不是很方便了?但是我們在用 Android Studio 開發(fā)的時候如果有一款插件是不是更方便了?所以這里推薦一個 AS 插件 ADB IDEA ,裝了這款插件可以直接在 AS 中快速操作一些 ADB 命令,非常方便。
安裝完成后,快捷鍵直接喚起:
Mac OSX: Ctrl+Shift+A
Windows/Linux: Ctrl+Alt+Shift+A
感謝朋友們無私的分享與補充(排名不分先后)。
zxning,linhua55,codeskyblue,seasonyuu,fan123199,zhEdward,0x8BADFOOD,keith666666,shawnlinboy。