使用adb命令控制Android
adb shell input text hello //把hello這個內容傳到有焦點的EditText之類的控件上
adb shell input keyevent 3 //相當于按下home鍵,4是返回鍵
adb shell input keyevent --longpress 3//相當于長按home鍵
adb shell input tap 250 200 //相當于觸摸一下x250,y200的坐標一下
adb shell input swipe 250 200 350 300 //相當于從x250,y200坐標滑動到x350,y300坐標
adb shell input swipe 250 200 350 300 1000 //相當于從x250,y200坐標滑動到x350,y300坐標,共花1000毫秒
adb shell input swipe 250 200 250 200 2000 //相當于長按x250,y200坐標2000秒,(其實是從x250,y200滑動到x250,y200,中間花了2000毫秒,但是位置未改變,所以識別為長按,安卓系統規定單次距離不超過8dp視為未移動)
adb shell screenrecord /sdcard/demo.mp4 //錄制視頻并保存為后面的路徑
adb shell screenrecord ?--time-limit 10 /sdcard/demo.mp4 //設置錄制的時間為10秒,默認為180秒
adb shell screenrecord --size 1280*720 /sdcard/demo.mp4 //指定視頻的分辨率,不指定默認使用手機的分辨率
adb shell screenrecord --bit-rate 6000000 /sdcard/demo.mp4 //指定比特率,默認為4Mbps
adb pull /sdcard/demo.mp4 //導出文件
ps:想獲取當前觸摸的xy值,可以打開"開發者選項"->"指針位置"即可
adb shell dumpsys activity activities //查看任務棧信息
adb tcpip 5555//在當前設備上打開端口
adb connect 192.168.3.81:5555//遠程連接該端口(可以遠程調試)
adb disconnect 192.168.3.161//斷開指定的遠程連接,不傳ip表示斷開所有的遠程連接
adb shell am start com.xx.xx/.MainActivity //啟動一個 activity
adb shell am broadcast -a magcomm.action.TOUCH_LETTER //發送一個廣播,使用 action
順便轉載一個老哥的文章,用法收集的很全,可以當成文檔(https://github.com/mzlogin/awesome-adb)
Android系統內運行shell命令的方法:https://mp.weixin.qq.com/s/IN9ooXWqgeHhOIbaOWYmAw
再加上這個:https://www.jianshu.com/p/56fd03f1aaae
下面是怕鏈接失效粘過來的
基本用法
命令語法
adb 命令的基本語法如下:
adb [-d|-e|-s <serialNumber>] <command>如果只有一個設備/模擬器連接時,可以省略掉?[-d|-e|-s <serialNumber>]?這一部分,直接使用?adb <command>。
為命令指定目標設備
如果有多個設備/模擬器連接,則需要為命令指定目標設備。
| -d | 指定當前唯一通過 USB 連接的 Android 設備為命令目標 |
| -e | 指定當前唯一運行的模擬器為命令目標 |
| -s <serialNumber> | 指定相應 serialNumber 號的設備/模擬器為命令目標 |
在多個設備/模擬器連接的情況下較常用的是?-s <serialNumber>?參數,serialNumber 可以通過?adb devices?命令獲取。如:
$ adb devicesList of devices attached cf264b8f device emulator-5554 device 10.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遇到多設備/模擬器的情況均使用這幾個參數為命令指定目標設備,下文中為簡化描述,不再重復。
啟動/停止
啟動 adb server 命令:
adb start-server(一般無需手動執行此命令,在運行 adb 命令時若發現 adb server 沒有啟動會自動調起。)
停止 adb server 命令:
adb kill-server查看 adb 版本
命令:
adb version示例輸出:
Android Debug Bridge version 1.0.36 Revision 8f855a3d9b35-android以 root 權限運行 adbd
adb 的運行原理是 PC 端的 adb server 與手機端的守護進程 adbd 建立連接,然后 PC 端的 adb client 通過 adb server 轉發命令,adbd 接收命令后解析運行。
所以如果 adbd 以普通權限執行,有些需要 root 權限才能執行的命令無法直接用?adb xxx?執行。這時可以?adb shell?然后?su后執行命令,也可以讓 adbd 以 root 權限執行,這個就能隨意執行高權限命令了。
命令:
adb root正常輸出:
restarting adbd as root現在再運行?adb shell,看看命令行提示符是不是變成?#?了?
有些手機 root 后也無法通過?adb root?命令讓 adbd 以 root 權限執行,比如三星的部分機型,會提示?adbd cannot run as root in production builds,此時可以先安裝 adbd Insecure,然后?adb root?試試。
相應地,如果要恢復 adbd 為非 root 權限的話,可以使用?adb unroot?命令。
指定 adb server 的網絡端口
命令:
adb -P <port> start-server默認端口為 5037。
設備連接管理
查詢已連接設備/模擬器
命令:
adb devices輸出示例:
List of devices attached cf264b8f device emulator-5554 device 10.129.164.6:5555 device輸出格式為?[serialNumber] [state],serialNumber 即我們常說的 SN,state 有如下幾種:
-
offline?—— 表示設備未連接成功或無響應。
-
device?—— 設備已連接。注意這個狀態并不能標識 Android 系統已經完全啟動和可操作,在設備啟動過程中設備實例就可連接到 adb,但啟動完畢后系統才處于可操作狀態。
-
no device?—— 沒有設備/模擬器連接。
以上輸出顯示當前已經連接了三臺設備/模擬器,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 attached cf264b8f offlineUSB 連接
通過 USB 連接來正常使用 adb 需要保證幾點:
硬件狀態正常。
包括 Android 設備處于正常開機狀態,USB 連接線和各種接口完好。
Android 設備的開發者選項和 USB 調試模式已開啟。
可以到「設置」-「開發者選項」-「Android 調試」查看。
如果在設置里找不到開發者選項,那需要通過一個彩蛋來讓它顯示出來:在「設置」-「關于手機」連續點擊「版本號」7 次。
設備驅動狀態正常。
這一點貌似在 Linux 和 Mac OS X 下不用操心,在 Windows 下有可能遇到需要安裝驅動的情況,確認這一點可以右鍵「計算機」-「屬性」,到「設備管理器」里查看相關設備上是否有黃色感嘆號或問號,如果沒有就說明驅動狀態已經好了。否則可以下載一個手機助手類程序來安裝驅動先。
通過 USB 線連接好電腦和設備后確認狀態。
adb devices如果能看到
xxxxxx device說明連接成功。
無線連接(需要借助 USB 線)
除了可以通過 USB 連接設備與電腦來使用 adb,也可以通過無線連接——雖然連接過程中也有需要使用 USB 的步驟,但是連接成功之后你的設備就可以在一定范圍內擺脫 USB 連接線的限制啦!
操作步驟:
將 Android 設備與要運行 adb 的電腦連接到同一個局域網,比如連到同一個 WiFi。
將設備與電腦通過 USB 線連接。
應確保連接成功(可運行?adb devices?看是否能列出該設備)。
讓設備在 5555 端口監聽 TCP/IP 連接:
adb tcpip 5555斷開 USB 連接。
找到設備的 IP 地址。
一般能在「設置」-「關于手機」-「狀態信息」-「IP地址」找到,也可以使用下文里?查看設備信息 - IP 地址?一節里的方法用 adb 命令來查看。
通過 IP 地址連接設備。
adb connect <device-ip-address>這里的?<device-ip-address>?就是上一步中找到的設備 IP 地址。
確認連接狀態。
adb devices如果能看到
<device-ip-address>:5555 device說明連接成功。
如果連接不了,請確認 Android 設備與電腦是連接到了同一個 WiFi,然后再次執行?adb connect <device-ip-address>?那一步;
如果還是不行的話,通過?adb kill-server?重新啟動 adb 然后從頭再來一次試試。
斷開無線連接
命令:
adb disconnect <device-ip-address>無線連接(無需借助 USB 線)
注:需要 root 權限。
上一節「無線連接(需要借助 USB 線)」是官方文檔里介紹的方法,需要借助于 USB 數據線來實現無線連接。
既然我們想要實現無線連接,那能不能所有步驟下來都是無線的呢?答案是能的。
在 Android 設備上安裝一個終端模擬器。
已經安裝過的設備可以跳過此步。我使用的終端模擬器下載地址是:Terminal Emulator for Android Downloads
將 Android 設備與要運行 adb 的電腦連接到同一個局域網,比如連到同一個 WiFi。
打開 Android 設備上的終端模擬器,在里面依次運行命令:
su setprop service.adb.tcp.port 5555找到 Android 設備的 IP 地址。
一般能在「設置」-「關于手機」-「狀態信息」-「IP地址」找到,也可以使用下文里?查看設備信息 - IP 地址?一節里的方法用 adb 命令來查看。
在電腦上通過 adb 和 IP 地址連接 Android 設備。
adb connect <device-ip-address>這里的?<device-ip-address>?就是上一步中找到的設備 IP 地址。
如果能看到?connected to <device-ip-address>:5555?這樣的輸出則表示連接成功。
節注一:
有的設備,比如小米 5S + MIUI 8.0 + Android 6.0.1 MXB48T,可能在第 5 步之前需要重啟 adbd 服務,在設備的終端模擬器上運行:
restart adbd如果 restart 無效,嘗試以下命令:
stop adbd start adbd應用管理
查看應用列表
查看應用列表的基本命令格式是
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>?字符串 |
所有應用
命令:
adb shell pm list packages輸出示例:
package:com.android.smoketest package:com.example.android.livecubes package:com.android.providers.telephony package:com.google.android.googlequicksearchbox package:com.android.providers.calendar package:com.android.providers.media package:com.android.protips package:com.android.documentsui package:com.android.gallery package:com.android.externalstorage ... // other packages here ...系統應用
命令:
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安裝 APK
命令格式:
adb install [-lrtsdg] <path_to_apk> 僅安裝: adb install 路徑 比如覆蓋相同或低版本: adb install -r -d 路徑參數:
adb install?后面可以跟一些可選參數來控制安裝 APK 的行為,可用參數及含義如下:
| -l | 將應用安裝到保護目錄 /mnt/asec |
| -r | 允許覆蓋安裝 |
| -t | 允許安裝 AndroidManifest.xml 里 application 指定?android:testOnly="true"?的應用 |
| -s | 將應用安裝到 sdcard |
| -d | 允許降級覆蓋安裝 |
| -g | 授予所有運行時權限 |
運行命令后如果見到類似如下輸出(狀態為?Success)代表安裝成功:
[100%] /data/local/tmp/1.apkpkg: /data/local/tmp/1.apk Success上面是當前最新版 v1.0.36 的 adb 的輸出,會顯示 push apk 文件到手機的進度百分比。
使用舊版本 adb 的輸出則是這樣的:
12040 KB/s (22205609 bytes in 1.801s)pkg: /data/local/tmp/SogouInput_android_v8.3_sweb.apk Success而如果狀態為?Failure?則表示安裝失敗,比如:
[100%] /data/local/tmp/map-20160831.apkpkg: /data/local/tmp/map-20160831.apk Failure [INSTALL_FAILED_ALREADY_EXISTS]常見安裝失敗輸出代碼、含義及可能的解決辦法如下:
| 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! | 已安裝該應用且簽名不一致 | 先卸載設備上的該應用,再安裝 |
參考:PackageManager.java
adb install?內部原理簡介
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><packagename>?表示應用名包,這條命令的效果相當于在設置里的應用信息界面點擊了「清除緩存」和「清除數據」。
命令示例:
adb shell pm clear com.qihoo360.mobilesafe表示清除 360 手機衛士的數據和緩存。
查看前臺 Activity
命令:
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。
查看正在運行的 Services
命令:
adb shell dumpsys activity services [<packagename>]<packagename>?參數不是必須的,指定?<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、安裝后的文件資源代碼等路徑、版本信息、權限信息和授予狀態、簽名版本信息等。
<packagename>?表示應用包名。
輸出示例:
Activity Resolver Table:Non-Data Actions:android.intent.action.MAIN:5b4cba8 org.mazhuang.guanggoo/.SplashActivity filter 5ec9dccAction: "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=10394pkg=Package{55f714c org.mazhuang.guanggoo}codePath=/data/app/org.mazhuang.guanggoo-2resourcePath=/data/app/org.mazhuang.guanggoo-2legacyNativeLibraryDir=/data/app/org.mazhuang.guanggoo-2/libprimaryCpuAbi=nullsecondaryCpuAbi=nullversionCode=74 minSdk=15 targetSdk=25versionName=1.1.74splits=[base]apkSigningVersion=2applicationInfo=ApplicationInfo{7754242 org.mazhuang.guanggoo}flags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]privateFlags=[ RESIZEABLE_ACTIVITIES ]dataDir=/data/user/0/org.mazhuang.guanggoosupportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]timeStamp=2017-10-22 23:50:53firstInstallTime=2017-10-22 23:50:25lastUpdateTime=2017-10-22 23:50:55installerPackageName=com.miui.packageinstallersignatures=PackageSignatures{af09595 [53c7caa2]}installPermissionsFixed=true installStatus=1pkgFlags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]requested permissions:android.permission.READ_PHONE_STATEandroid.permission.INTERNETandroid.permission.ACCESS_NETWORK_STATEandroid.permission.ACCESS_WIFI_STATEandroid.permission.READ_LOGSandroid.permission.WRITE_EXTERNAL_STORAGEandroid.permission.READ_EXTERNAL_STORAGEinstall permissions:android.permission.INTERNET: granted=trueandroid.permission.ACCESS_NETWORK_STATE: granted=trueandroid.permission.ACCESS_WIFI_STATE: granted=trueUser 0: ceDataInode=1155675 installed=true hidden=false suspended=false stopped=true notLaunched=false enabled=0gids=[3003]runtime permissions:android.permission.READ_EXTERNAL_STORAGE: granted=trueandroid.permission.READ_PHONE_STATE: granted=trueandroid.permission.WRITE_EXTERNAL_STORAGE: granted=trueUser 999: ceDataInode=0 installed=false hidden=false suspended=false stopped=true notLaunched=true enabled=0gids=[3003]runtime permissions:Dexopt state:[org.mazhuang.guanggoo]Instruction Set: arm64path: /data/app/org.mazhuang.guanggoo-2/base.apkstatus: /data/app/org.mazhuang.guanggoo-2/oat/arm64/base.odex [compilation_filter=speed-profile, status=kOatUpToDate]查看應用安裝路徑
命令:
adb shell pm path <PACKAGE>輸出應用安裝路徑
輸出示例:
adb shell pm path ecarx.weatherpackage:/data/app/ecarx.weather-1.apk與應用交互
主要是使用?am <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 |
<INTENT>?里還能帶數據,就像寫代碼時的 Bundle 一樣:
| --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 數組 |
| --ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...] | long 數組 |
啟動應用/ 調起 Activity
命令格式:
adb shell am start [options] <INTENT>例如:
adb shell am start -n com.tencent.mm/.ui.LauncherUI表示調起微信主界面。
adb shell am start -n org.mazhuang.boottimemeasure/.MainActivity --es "toast" "hello, world"表示調起?org.mazhuang.boottimemeasure/.MainActivity?并傳給它 string 數據鍵值對?toast - hello, world。
調起 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/.BootCompletedReceiver這類用法在測試的時候很實用,比如某個廣播的場景很難制造,可以考慮通過這種方式來發送廣播。
既能發送系統預定義的廣播,也能發送自定義廣播。如下是部分系統預定義廣播及正常觸發時機:
| 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 安全衛士的一切進程與服務。
收緊內存
命令:
adb shell am send-trim-memory <pid> <level>pid: 進程 ID level: HIDDEN、RUNNING_MODERATE、BACKGROUND、 RUNNING_LOW、MODERATE、RUNNING_CRITICAL、COMPLETE
命令示例:
adb shell am send-trim-memory 12345 RUNNING_LOW表示向 pid=12345 的進程,發出 level=RUNNING_LOW 的收緊內存命令。
文件管理
復制設備里的文件到電腦
命令:
adb pull <設備里的文件路徑> [電腦上的目錄]其中?電腦上的目錄?參數可以省略,默認復制到當前目錄。
例:
adb pull /sdcard/sr.mp4 ~/tmp/*小技巧:*設備上的文件路徑可能需要 root 權限才能訪問,如果你的設備已經 root 過,可以先使用?adb shell?和?su?命令在 adb shell 里獲取 root 權限后,先?cp /path/on/device /sdcard/filename?將文件復制到 sdcard,然后?adb pull /sdcard/filename /path/on/pc。
復制電腦里的文件到設備
命令:
adb push <電腦上的文件路徑> <設備里的目錄>例:
adb push ~/sr.mp4 /sdcard/*小技巧:*設備上的文件路徑普通權限可能無法直接寫入,如果你的設備已經 root 過,可以先?adb push /path/on/pc /sdcard/filename,然后?adb shell?和?su?在 adb shell 里獲取 root 權限后,cp /sdcard/filename /path/on/device。
模擬按鍵/輸入
在?adb shell?里有個很實用的命令叫?input,通過它可以做一些有趣的事情。
input?命令的完整 help 信息如下:
Usage: input [<source>] <command> [<arg>...]The sources are:mousekeyboardjoysticktouchnavigationtouchpadtrackballstylusdpadgesturetouchscreengamepadThe 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,摘引部分我覺得有意思的如下:
| 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 82HOME 鍵
命令:
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 系統的日志分為兩部分,底層的 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 日志)。
日志格式
可以用?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]?代表內核開始啟動后的時間,單位為秒。
通過內核日志我們可以做一些事情,比如衡量內核啟動時間,在系統啟動完畢后的內核日志里找到?Freeing init memory?那一行前面的時間就是。
查看設備信息
型號
命令:
adb shell getprop ro.product.model輸出示例:
Nexus 5電池狀況
命令:
adb shell dumpsys battery輸入示例:
Current Battery Service state:AC powered: falseUSB powered: trueWireless powered: falsestatus: 2health: 2present: truelevel: 44scale: 100voltage: 3872temperature: 280technology: Li-poly其中?scale?代表最大電量,level?代表當前電量。上面的輸出表示還剩下 44% 的電量。
屏幕分辨率
命令:
adb shell wm size輸出示例:
Physical size: 1080x1920該設備屏幕分辨率為 1080px * 1920px。
如果使用命令修改過,那輸出可能是:
Physical size: 1080x1920 Override size: 480x1024表明設備的屏幕分辨率原本是 1080px * 1920px,當前被修改為 480px * 1024px。
屏幕密度
命令:
adb shell wm density輸出示例:
Physical density: 420該設備屏幕密度為 420dpi。
如果使用命令修改過,那輸出可能是:
Physical density: 480 Override density: 160表明設備的屏幕密度原來是 480dpi,當前被修改為 160dpi。
顯示屏參數
命令:
adb shell dumpsys window displays輸出示例:
WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)Display: mDisplayId=0init=1080x1920 420dpi cur=1080x1920 app=1080x1794 rng=1080x1017-1810x1731deferred=false layoutNeeded=false其中?mDisplayId?為 顯示屏編號,init?是初始分辨率和屏幕密度,app?的高度比?init?里的要小,表示屏幕底部有虛擬按鍵,高度為 1920 - 1794 = 126px 合 42dp。
android_id
命令:
adb shell settings get secure android_id輸出示例:
51b6be48bac8c569IMEI
在 Android 4.4 及以下版本可通過如下命令獲取 IMEI:
adb?shell?dumpsys?iphonesubinfo輸出示例:
Phone Subscriber Info:Phone Type = GSMDevice ID = 860955027785041其中的?Device ID?就是 IMEI。
而在 Android 5.0 及以上版本里這個命令輸出為空,得通過其它方式獲取了(需要 root 權限):
adb shell su service 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... ')把里面的有效內容提取出來就是 IMEI 了,比如這里的是?860955027785041。
參考:adb shell dumpsys iphonesubinfo not working since Android 5.0 Lollipop
Android 系統版本
命令:
adb shell getprop ro.build.version.release輸出示例:
5.0.2IP 地址
每次想知道設備的 IP 地址的時候都得「設置」-「關于手機」-「狀態信息」-「IP地址」很煩對不對?通過 adb 可以方便地查看。
命令:
adb shell ifconfig | grep Mask輸出示例:
inet addr:10.130.245.230 Mask:255.255.255.252 inet addr:127.0.0.1 Mask:255.0.0.0那么?10.130.245.230?就是設備 IP 地址。
在有的設備上這個命令沒有輸出,如果設備連著 WiFi,可以使用如下命令來查看局域網 IP:
adb shell ifconfig wlan0輸出示例:
wlan0: ip 10.129.160.99 mask 255.255.240.0 flags [up broadcast running multicast]或
wlan0 Link encap:UNSPECinet addr:10.129.168.57 Bcast:10.129.175.255 Mask:255.255.240.0inet6 addr: fe80::66cc:2eff:fe68:b6b6/64 Scope: LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:496520 errors:0 dropped:0 overruns:0 frame:0TX packets:68215 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:3000RX bytes:116266821 TX bytes:8311736如果以上命令仍然不能得到期望的信息,那可以試試以下命令(部分系統版本里可用):
adb shell netcfg輸出示例:
wlan0 UP 10.129.160.99/20 0x00001043 f8:a9:d0:17:42:4d lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00 p2p0 UP 0.0.0.0/0 0x00001003 fa:a9:d0:17:42:4d sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00 rmnet0 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 rmnet1 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 rmnet3 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 rmnet2 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 rmnet4 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 rmnet6 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 rmnet5 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 rmnet7 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 rev_rmnet3 DOWN 0.0.0.0/0 0x00001002 4e:b7:e4:2e:17:58 rev_rmnet2 DOWN 0.0.0.0/0 0x00001002 4e:f0:c8:bf:7a:cf rev_rmnet4 DOWN 0.0.0.0/0 0x00001002 a6:c0:3b:6b:c4:1f rev_rmnet6 DOWN 0.0.0.0/0 0x00001002 66:bb:5d:64:2e:e9 rev_rmnet5 DOWN 0.0.0.0/0 0x00001002 0e:1b:eb:b9:23:a0 rev_rmnet7 DOWN 0.0.0.0/0 0x00001002 7a:d9:f6:81:40:5a rev_rmnet8 DOWN 0.0.0.0/0 0x00001002 4e:e2:a9:bb:d0:1b rev_rmnet0 DOWN 0.0.0.0/0 0x00001002 fe:65:d0:ca:82:a9 rev_rmnet1 DOWN 0.0.0.0/0 0x00001002 da:d8:e8:4f:2e:fe可以看到網絡連接名稱、啟用狀態、IP 地址和 Mac 地址等信息。
Mac 地址
命令:
adb shell cat /sys/class/net/wlan0/address輸出示例:
f8:a9:d0:17:42:4d這查看的是局域網 Mac 地址,移動網絡或其它連接的信息可以通過前面的小節「IP 地址」里提到的?adb shell netcfg?命令來查看。
CPU 信息
命令:
adb shell cat /proc/cpuinfo輸出示例:
Processor : ARMv7 Processor rev 0 (v7l) processor : 0 BogoMIPS : 38.40processor : 1 BogoMIPS : 38.40processor : 2 BogoMIPS : 38.40processor : 3 BogoMIPS : 38.40Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt CPU implementer : 0x51 CPU architecture: 7 CPU variant : 0x2 CPU part : 0x06f CPU revision : 0Hardware : Qualcomm MSM 8974 HAMMERHEAD (Flattened Device Tree) Revision : 000b Serial : 0000000000000000這是 Nexus 5 的 CPU 信息,我們從輸出里可以看到使用的硬件是?Qualcomm MSM 8974,processor 的編號是 0 到 3,所以它是四核的,采用的架構是?ARMv7 Processor rev 0 (v71)。
內存信息
命令:
adb shell cat /proc/meminfo輸出示例:
MemTotal: 1027424 kB MemFree: 486564 kB Buffers: 15224 kB Cached: 72464 kB SwapCached: 24152 kB Active: 110572 kB Inactive: 259060 kB Active(anon): 79176 kB Inactive(anon): 207736 kB Active(file): 31396 kB Inactive(file): 51324 kB Unevictable: 3948 kB Mlocked: 0 kB HighTotal: 409600 kB HighFree: 132612 kB LowTotal: 617824 kB LowFree: 353952 kB SwapTotal: 262140 kB SwapFree: 207572 kB Dirty: 0 kB Writeback: 0 kB AnonPages: 265324 kB Mapped: 47072 kB Shmem: 1020 kB Slab: 57372 kB SReclaimable: 7692 kB SUnreclaim: 49680 kB KernelStack: 4512 kB PageTables: 5912 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 775852 kB Committed_AS: 13520632 kB VmallocTotal: 385024 kB VmallocUsed: 61004 kB VmallocChunk: 209668 kB其中,MemTotal?就是設備的總內存,MemFree?是當前空閑內存。
更多硬件與系統屬性
設備的更多硬件與系統屬性可以通過如下命令查看:
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修改設置
注:?修改設置之后,運行恢復命令有可能顯示仍然不太正常,可以運行?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四個數字分別表示距離左、上、右、下邊緣的留白像素,以上命令表示將屏幕底部 200px 留白。
恢復原顯示區域命令:
adb shell wm overscan reset關閉 USB 調試模式
命令:
adb shell settings put global adb_enabled 0恢復:
用命令恢復不了了,畢竟關閉了 USB 調試 adb 就連接不上 Android 設備了。
去設備上手動恢復吧:「設置」-「開發者選項」-「Android 調試」。
允許/禁止訪問非 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 | 禁止調用黑名單中的接口,但允許調用深灰名單中的接口。 |
狀態欄和導航欄的顯示隱藏
本節所說的相關設置對應 Cyanogenmod 里的「擴展桌面」。
命令:
adb shell settings put global policy_control <key-values><key-values>?可由如下幾種鍵及其對應的值組成,格式為?<key1>=<value1>:<key2>=<value2>。
| immersive.full | 同時隱藏 |
| immersive.status | 隱藏狀態欄 |
| immersive.navigation | 隱藏導航欄 |
| immersive.preconfirms | ? |
這些鍵對應的值可則如下值用逗號組合:
| apps | 所有應用 |
| * | 所有界面 |
| packagename | 指定應用 |
| -packagename | 排除指定應用 |
例如:
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?的所有應用里隱藏導航欄。
實用功能
屏幕截圖
截圖保存到電腦:
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.pngMac 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錄制屏幕
錄制屏幕以 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 | 輸出更多信息。 |
重新掛載 system 分區為可寫
注:需要 root 權限。
/system 分區默認掛載為只讀,但有些操作比如給 Android 系統添加命令、刪除自帶應用等需要對 /system 進行寫操作,所以需要重新掛載它為可讀寫。
步驟:
進入 shell 并切換到 root 用戶權限。
命令:
adb shell su查看當前分區掛載情況。
命令:
mount輸出示例:
rootfs / rootfs ro,relatime 0 0 tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,mode=755 0 0 devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0 proc /proc proc rw,relatime 0 0 sysfs /sys sysfs rw,seclabel,relatime 0 0 selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0 debugfs /sys/kernel/debug debugfs rw,relatime 0 0 none /var tmpfs rw,seclabel,relatime,mode=770,gid=1000 0 0 none /acct cgroup rw,relatime,cpuacct 0 0 none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0 none /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0 tmpfs /mnt/asec tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0 tmpfs /mnt/obb tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0 none /dev/memcg cgroup rw,relatime,memory 0 0 none /dev/cpuctl cgroup rw,relatime,cpu 0 0 none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0 none /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0 none /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 下的文件為所欲為了。
查看連接過的 WiFi 密碼
注:需要 root 權限。
命令:
adb shell su cat /data/misc/wifi/*.conf輸出示例:
network={ssid="TP-LINK_9DFC"scan_ssid=1psk="123456789"key_mgmt=WPA-PSKgroup=CCMP TKIPauth_alg=OPENsim_num=1priority=13893 }network={ssid="TP-LINK_F11E"psk="987654321"key_mgmt=WPA-PSKsim_num=1priority=17293 }ssid?即為我們在 WLAN 設置里看到的名稱,psk?為密碼,key_mgmt?為安全加密方式。
設置系統日期和時間
注:需要 root 權限。
命令:
adb shell su date -s 20160823.131500表示將系統日期和時間更改為 2016 年 08 月 23 日 13 點 15 分 00 秒。
重啟手機
命令:
adb reboot檢測設備是否已 root
命令:
adb shell su此時命令行提示符是?$?則表示沒有 root 權限,是?#?則表示已 root。
使用 Monkey 進行壓力測試
Monkey 可以生成偽隨機用戶事件來模擬單擊、觸摸、手勢等操作,可以對正在開發中的程序進行隨機壓力測試。
簡單用法:
adb shell monkey -p <packagename> -v 500表示向?<packagename>?指定的應用程序發送 500 個偽隨機事件。
Monkey 的詳細用法參考?官方文檔。
開啟/關閉 WiFi
注:需要 root 權限。
有時需要控制設備的 WiFi 狀態,可以用以下指令完成。
開啟 WiFi:
adb root adb shell svc wifi enable關閉 WiFi:
adb root adb shell svc wifi disable若執行成功,輸出為空;若未取得 root 權限執行此命令,將執行失敗,輸出?Killed。
刷機相關命令
重啟到 Recovery 模式
命令:
adb reboot recovery從 Recovery 重啟到 Android
命令:
adb reboot重啟到 Fastboot 模式
命令:
adb reboot bootloader通過 sideload 更新系統
如果我們下載了 Android 設備對應的系統更新包到電腦上,那么也可以通過 adb 來完成更新。
以 Recovery 模式下更新為例:
重啟到 Recovery 模式。
命令:
adb reboot recovery在設備的 Recovery 界面上操作進入?Apply update-Apply from ADB。
注:不同的 Recovery 菜單可能與此有差異,有的是一級菜單就有?Apply update from ADB。
通過 adb 上傳和更新系統。
命令:
adb sideload <path-to-update.zip>安全相關命令
啟用/禁用 SELinux
啟用 SELinux
adb root adb shell setenforce 1禁用 SELinux
adb root adb shell setenforce 0啟用/禁用 dm_verity
啟用 dm_verity
adb root adb enable-verity禁用 dm_verity
adb root adb disable-verity更多 adb shell 命令
Android 系統是基于 Linux 內核的,所以 Linux 里的很多命令在 Android 里也有相同或類似的實現,在?adb shell?里可以調用。本文檔前面的部分內容已經用到了?adb shell?命令。
查看進程
命令:
adb shell ps輸出示例:
USER PID PPID VSIZE RSS WCHAN PC NAME root 1 0 8904 788 ffffffff 00000000 S /init root 2 0 0 0 ffffffff 00000000 S kthreadd ... u0_a71 7779 5926 1538748 48896 ffffffff 00000000 S com.sohu.inputmethod.sogou:classic u0_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 = 307PID PR CPU% S #THR VSS RSS PCY UID Name8763 0 3% R 1 10640K 1064K fg shell top131 0 3% S 1 0K 0K fg root dhd_dpc6144 0 0% S 115 1682004K 115916K fg system system_server132 0 0% S 1 0K 0K fg root dhd_rxf1731 0 0% S 6 20288K 788K fg root /system/bin/mpdecision217 0 0% S 6 18008K 356K fg shell /sbin/adbd...7779 2 0% S 19 1538748K 48896K bg u0_a71 com.sohu.inputmethod.sogou:classic7963 0 0% S 18 1561916K 59568K fg u0_a58 org.mazhuang.boottimemeasure...各列含義:
| 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 | 進程名 |
top?命令還支持一些命令行參數,詳細用法如下:
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 顯示幫助文檔查看進程 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:/ $其它
如下是其它常用命令的簡單描述,前文已經專門講過的命令不再額外說明:
| cat | 顯示文件內容 |
| cd | 切換目錄 |
| chmod | 改變文件的存取模式/訪問權限 |
| df | 查看磁盤空間使用情況 |
| grep | 過濾輸出 |
| kill | 殺死指定 PID 的進程 |
| ls | 列舉目錄內容 |
| mount | 掛載目錄的查看和管理 |
| mv | 移動或重命名文件 |
| ps | 查看正在運行的進程 |
| rm | 刪除文件 |
| top | 查看進程的資源占用情況 |
常見問題
啟動 adb server 失敗
出錯提示
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,用命令結束該進程:
taskkill /PID 1548然后再啟動 adb 就沒問題了。
com.android.ddmlib.AdbCommandRejectedException
在 Android Studio 里新建一個模擬器,但是用 adb 一直連接不上,提示:
com.android.ddmlib.AdbCommandRejectedException: device unauthorized. This adb server's $ADB_VENDOR_KEYS is not set Try 'adb kill-server' if that seems wrong. Otherwise check for a confirmation dialog on your device.在手機上安裝一個終端然后執行 su 提示沒有該命令,這不正常。
于是刪除該模擬器后重新下載安裝一次,這次就正常了。
adb 的非官方實現
- fb-adb?- A better shell for Android devices (for Mac).
相關命令
- aapt
- am
- dumsys
- pm
- uiautomator
總結
以上是生活随笔為你收集整理的使用adb命令控制Android的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RecyclerView添加头条目显示空
- 下一篇: 使用ORM数据库:greenDao