<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                文檔當前狀態:**alpha0.1** * [x] 選題收集:2018/01/05 * [ ] 初稿整理: * [ ] 補充校對: * [ ] 入庫存檔: --- [TOC] # ![Awesome Adb](https://github.com/mzlogin/awesome-adb/raw/master/assets/title.png) ADB,即 [Android Debug Bridge](https://developer.android.com/studio/command-line/adb.html),它是 Android 開發/測試人員不可替代的強大工具,也是 Android 設備玩家的好玩具。 持續更新中,歡迎提 PR 和 Issue 補充指正,覺得有用的可以將 [此 GitHub 倉庫](https://github.com/mzlogin/awesome-adb) Star 收藏備用。 **注:** 有部分命令的支持情況可能與 Android 系統版本及定制 ROM 的實現有關。 Other languages: [:gb: English](./README.en.md) # ![Table of Contents](https://github.com/mzlogin/awesome-adb/raw/master/assets/toc.png) ## 基本用法 ### 命令語法 adb 命令的基本語法如下: ```sh adb [-d|-e|-s <serialNumber>] <command> ``` 如果只有一個設備/模擬器連接時,可以省略掉 `[-d|-e|-s <serialNumber>]` 這一部分,直接使用 `adb <command>`。 ### 為命令指定目標設備 如果有多個設備/模擬器連接,則需要為命令指定目標設備。 | 參數 | 含義 | |---------------------|----------------------------------------------------| | -d | 指定當前唯一通過 USB 連接的 Android 設備為命令目標 | | -e | 指定當前唯一運行的模擬器為命令目標 | | `-s <serialNumber>` | 指定相應 serialNumber 號的設備/模擬器為命令目標 | 在多個設備/模擬器連接的情況下較常用的是 `-s <serialNumber>` 參數,serialNumber 可以通過 `adb devices` 命令獲取。如: ```sh $ adb devices List 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 命令獲取屏幕分辨率: ```sh adb -s cf264b8f shell wm size ``` 又如想給 `10.129.164.6:5555` 這個設備安裝應用(*這種形式的 serialNumber 格式為 `<IP>:<Port>`,一般為無線連接的設備或 Genymotion 等第三方 Android 模擬器*): ```sh adb -s 10.129.164.6:5555 install test.apk ``` **遇到多設備/模擬器的情況均使用這幾個參數為命令指定目標設備,下文中為簡化描述,不再重復。** ### 啟動/停止 啟動 adb server 命令: ```sh adb start-server ``` (一般無需手動執行此命令,在運行 adb 命令時若發現 adb server 沒有啟動會自動調起。) 停止 adb server 命令: ```sh adb kill-server ``` ### 查看 adb 版本 命令: ```sh adb version ``` 示例輸出: ```sh 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 權限執行,這個就能隨意執行高權限命令了。 命令: ```sh adb root ``` 正常輸出: ```sh 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 的網絡端口 命令: ```sh adb -P <port> start-server ``` 默認端口為 5037。 ## 設備連接管理 ### 查詢已連接設備/模擬器 命令: ```sh adb devices ``` 輸出示例: ```sh 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 模擬器。 常見異常輸出: 1. 沒有設備/模擬器連接成功。 ```sh List of devices attached ``` 2. 設備/模擬器未連接到 adb 或無響應。 ```sh List of devices attached cf264b8f offline ``` ### USB 連接 通過 USB 連接來正常使用 adb 需要保證幾點: 1. 硬件狀態正常。 包括 Android 設備處于正常開機狀態,USB 連接線和各種接口完好。 2. Android 設備的開發者選項和 USB 調試模式已開啟。 可以到「設置」-「開發者選項」-「Android 調試」查看。 如果在設置里找不到開發者選項,那需要通過一個彩蛋來讓它顯示出來:在「設置」-「關于手機」連續點擊「版本號」7 次。 3. 設備驅動狀態正常。 這一點貌似在 Linux 和 Mac OS X 下不用操心,在 Windows 下有可能遇到需要安裝驅動的情況,確認這一點可以右鍵「計算機」-「屬性」,到「設備管理器」里查看相關設備上是否有黃色感嘆號或問號,如果沒有就說明驅動狀態已經好了。否則可以下載一個手機助手類程序來安裝驅動先。 4. 通過 USB 線連接好電腦和設備后確認狀態。 ```sh adb devices ``` 如果能看到 ```sh xxxxxx device ``` 說明連接成功。 ### 無線連接(需要借助 USB 線) 除了可以通過 USB 連接設備與電腦來使用 adb,也可以通過無線連接——雖然連接過程中也有需要使用 USB 的步驟,但是連接成功之后你的設備就可以在一定范圍內擺脫 USB 連接線的限制啦! 操作步驟: 1. 將 Android 設備與要運行 adb 的電腦連接到同一個局域網,比如連到同一個 WiFi。 2. 將設備與電腦通過 USB 線連接。 應確保連接成功(可運行 `adb devices` 看是否能列出該設備)。 3. 讓設備在 5555 端口監聽 TCP/IP 連接: ```sh adb tcpip 5555 ``` 4. 斷開 USB 連接。 5. 找到設備的 IP 地址。 一般能在「設置」-「關于手機」-「狀態信息」-「IP地址」找到,也可以使用下文里 [查看設備信息 - IP 地址][1] 一節里的方法用 adb 命令來查看。 6. 通過 IP 地址連接設備。 ```sh adb connect <device-ip-address> ``` 這里的 `<device-ip-address>` 就是上一步中找到的設備 IP 地址。 7. 確認連接狀態。 ```sh adb devices ``` 如果能看到 ```sh <device-ip-address>:5555 device ``` 說明連接成功。 如果連接不了,請確認 Android 設備與電腦是連接到了同一個 WiFi,然后再次執行 `adb connect <device-ip-address>` 那一步; 如果還是不行的話,通過 `adb kill-server` 重新啟動 adb 然后從頭再來一次試試。 **斷開無線連接** 命令: ```sh adb disconnect <device-ip-address> ``` ### 無線連接(無需借助 USB 線) **注:需要 root 權限。** 上一節「無線連接(需要借助 USB 線)」是官方文檔里介紹的方法,需要借助于 USB 數據線來實現無線連接。 既然我們想要實現無線連接,那能不能所有步驟下來都是無線的呢?答案是能的。 1. 在 Android 設備上安裝一個終端模擬器。 已經安裝過的設備可以跳過此步。我使用的終端模擬器下載地址是:[Terminal Emulator for Android Downloads](https://jackpal.github.io/Android-Terminal-Emulator/) 2. 將 Android 設備與要運行 adb 的電腦連接到同一個局域網,比如連到同一個 WiFi。 3. 打開 Android 設備上的終端模擬器,在里面依次運行命令: ```sh su setprop service.adb.tcp.port 5555 ``` 4. 找到 Android 設備的 IP 地址。 一般能在「設置」-「關于手機」-「狀態信息」-「IP地址」找到,也可以使用下文里 [查看設備信息 - IP 地址][1] 一節里的方法用 adb 命令來查看。 5. 在電腦上通過 adb 和 IP 地址連接 Android 設備。 ```sh 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 服務,在設備的終端模擬器上運行: ```sh restart adbd ``` 如果 restart 無效,嘗試以下命令: ```sh stop adbd start adbd ``` ## 應用管理 ### 查看應用列表 查看應用列表的基本命令格式是 ```sh 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>` 字符串 | #### 所有應用 命令: ```sh adb shell pm list packages ``` 輸出示例: ```sh 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 ... ``` #### 系統應用 命令: ```sh adb shell pm list packages -s ``` #### 第三方應用 命令: ```sh adb shell pm list packages -3 ``` #### 包名包含某字符串的應用 比如要查看包名包含字符串 `mazhuang` 的應用列表,命令: ```sh adb shell pm list packages mazhuang ``` 當然也可以使用 grep 來過濾: ```sh adb shell pm list packages | grep mazhuang ``` ### 安裝 APK 命令格式: ```sh adb install [-lrtsdg] <path_to_apk> ``` 參數: `adb install` 后面可以跟一些可選參數來控制安裝 APK 的行為,可用參數及含義如下: | 參數 | 含義 | |------|-----------------------------------------------------------------------------------| | -l | 將應用安裝到保護目錄 /mnt/asec | | -r | 允許覆蓋安裝 | | -t | 允許安裝 AndroidManifest.xml 里 application 指定 `android:testOnly="true"` 的應用 | | -s | 將應用安裝到 sdcard | | -d | 允許降級覆蓋安裝 | | -g | 授予所有運行時權限 | 運行命令后如果見到類似如下輸出(狀態為 `Success`)代表安裝成功: ```sh [100%] /data/local/tmp/1.apk pkg: /data/local/tmp/1.apk Success ``` 上面是當前最新版 v1.0.36 的 adb 的輸出,會顯示 push apk 文件到手機的進度百分比。 使用舊版本 adb 的輸出則是這樣的: ```sh 12040 KB/s (22205609 bytes in 1.801s) pkg: /data/local/tmp/SogouInput_android_v8.3_sweb.apk Success ``` 而如果狀態為 `Failure` 則表示安裝失敗,比如: ```sh [100%] /data/local/tmp/map-20160831.apk pkg: /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 訪問失敗;<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 | 用戶被限制安裝應用 | | | INSTALL\_FAILED\_DUPLICATE\_PERMISSION | 應用嘗試定義一個已經存在的權限名稱 | | | 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 | 設備未授權允許調試 | | | 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](https://github.com/android/platform_frameworks_base/blob/master/core%2Fjava%2Fandroid%2Fcontent%2Fpm%2FPackageManager.java) *`adb install` 內部原理簡介* `adb install` 實際是分三步完成: 1. push apk 文件到 /data/local/tmp。 2. 調用 pm install 安裝。 3. 刪除 /data/local/tmp 下的對應 apk 文件。 所以,必要的時候也可以根據這個步驟,手動分步執行安裝過程。 ### 卸載應用 命令: ```sh adb uninstall [-k] <packagename> ``` `<packagename>` 表示應用的包名,`-k` 參數可選,表示卸載應用但保留數據和緩存目錄。 命令示例: ```sh adb uninstall com.qihoo360.mobilesafe ``` 表示卸載 360 手機衛士。 ### 清除應用數據與緩存 命令: ```sh adb shell pm clear <packagename> ``` `<packagename>` 表示應用名包,這條命令的效果相當于在設置里的應用信息界面點擊了「清除緩存」和「清除數據」。 命令示例: ```sh adb shell pm clear com.qihoo360.mobilesafe ``` 表示清除 360 手機衛士的數據和緩存。 ### 查看前臺 Activity 命令: ```sh adb shell dumpsys activity activities | grep mFocusedActivity ``` 輸出示例: ```sh mFocusedActivity: ActivityRecord{8079d7e u0 com.cyanogenmod.trebuchet/com.android.launcher3.Launcher t42} ``` 其中的 `com.cyanogenmod.trebuchet/com.android.launcher3.Launcher` 就是當前處于前臺的 Activity。 ### 查看正在運行的 Services 命令: ```sh 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 都會列出來。 ### 查看應用詳細信息 命令: ```sh adb shell dumpsys package <packagename> ``` 輸出中包含很多信息,包括 Activity Resolver Table、Registered ContentProviders、包名、userId、安裝后的文件資源代碼等路徑、版本信息、權限信息和授予狀態、簽名版本信息等。 `<packagename>` 表示應用包名。 輸出示例: ```sh 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=false Registered 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: 501 Packages: 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>` | 發送 `<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>` | string 值 | | `--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE>` | boolean 值 | | `--ei <EXTRA_KEY> <EXTRA_INT_VALUE>` | integer 值 | | `--el <EXTRA_KEY> <EXTRA_LONG_VALUE>` | long 值 | | `--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE>` | float 值 | | `--eu <EXTRA_KEY> <EXTRA_URI_VALUE>` | URI | | `--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>` | component name | | `--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]` | integer 數組 | | `--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]` | long 數組 | ### 調起 Activity 命令格式: ```sh adb shell am start [options] <INTENT> ``` 例如: ```sh adb shell am start -n com.tencent.mm/.ui.LauncherUI ``` 表示調起微信主界面。 ```sh adb shell am start -n org.mazhuang.boottimemeasure/.MainActivity --es "toast" "hello, world" ``` 表示調起 `org.mazhuang.boottimemeasure/.MainActivity` 并傳給它 string 數據鍵值對 `toast - hello, world`。 ### 調起 Service 命令格式: ```sh adb shell am startservice [options] <INTENT> ``` 例如: ```sh adb shell am startservice -n com.tencent.mm/.plugin.accountsync.model.AccountAuthenticatorService ``` 表示調起微信的某 Service。 ### 發送廣播 命令格式: ```sh adb shell am broadcast [options] <INTENT> ``` 可以向所有組件廣播,也可以只向指定組件廣播。 例如,向所有組件廣播 `BOOT_COMPLETED`: ```sh adb shell am broadcast -a android.intent.action.BOOT_COMPLETED ``` 又例如,只向 `org.mazhuang.boottimemeasure/.BootCompletedReceiver` 廣播 `BOOT_COMPLETED`: ```sh adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -n org.mazhuang.boottimemeasure/.BootCompletedReceiver ``` 這類用法在測試的時候很實用,比如某個廣播的場景很難制造,可以考慮通過這種方式來發送廣播。 既能發送系統預定義的廣播,也能發送自定義廣播。如下是部分系統預定義廣播及正常觸發時機: | 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 觸發)* ### 強制停止應用 命令: ```sh adb shell am force-stop <packagename> ``` 命令示例: ```sh adb shell am force-stop com.qihoo360.mobilesafe ``` 表示停止 360 安全衛士的一切進程與服務。 ## 文件管理 ### 復制設備里的文件到電腦 命令: ```sh adb pull <設備里的文件路徑> [電腦上的目錄] ``` 其中 `電腦上的目錄` 參數可以省略,默認復制到當前目錄。 例: ```sh 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`。 ### 復制電腦里的文件到設備 命令: ```sh adb push <電腦上的文件路徑> <設備里的目錄> ``` 例: ```sh 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 信息如下: ```sh 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](https://developer.android.com/reference/android/view/KeyEvent.html),摘引部分我覺得有意思的如下: | 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` 命令的一些用法舉例。 ### 電源鍵 命令: ```sh adb shell input keyevent 26 ``` 執行效果相當于按電源鍵。 ### 菜單鍵 命令: ```sh adb shell input keyevent 82 ``` ### HOME 鍵 命令: ```sh adb shell input keyevent 3 ``` ### 返回鍵 命令: ```sh adb shell input keyevent 4 ``` ### 音量控制 增加音量: ```sh adb shell input keyevent 24 ``` 降低音量: ```sh adb shell input keyevent 25 ``` 靜音: ```sh adb shell input keyevent 164 ``` ### 媒體控制 播放/暫停: ```sh adb shell input keyevent 85 ``` 停止播放: ```sh adb shell input keyevent 86 ``` 播放下一首: ```sh adb shell input keyevent 87 ``` 播放上一首: ```sh adb shell input keyevent 88 ``` 恢復播放: ```sh adb shell input keyevent 126 ``` 暫停播放: ```sh adb shell input keyevent 127 ``` ### 點亮/熄滅屏幕 可以通過上文講述過的模擬電源鍵來切換點亮和熄滅屏幕,但如果明確地想要點亮或者熄滅屏幕,那可以使用如下方法。 點亮屏幕: ```sh adb shell input keyevent 224 ``` 熄滅屏幕: ```sh adb shell input keyevent 223 ``` ### 滑動解鎖 如果鎖屏沒有密碼,是通過滑動手勢解鎖,那么可以通過 `input swipe` 來解鎖。 命令(參數以機型 Nexus 5,向上滑動手勢解鎖舉例): ```sh adb shell input swipe 300 1000 300 500 ``` 參數 `300 1000 300 500` 分別表示`起始點x坐標 起始點y坐標 結束點x坐標 結束點y坐標`。 ### 輸入文本 在焦點處于某文本框時,可以通過 `input` 命令來輸入文本。 命令: ```sh adb shell input text hello ``` 現在 `hello` 出現在文本框了。 ## 查看日志 Android 系統的日志分為兩部分,底層的 Linux 內核日志輸出到 /proc/kmsg,Android 的日志輸出到 /dev/log。 ### Android 日志 命令格式: ```sh [adb] logcat [<option>] ... [<filter-spec>] ... ``` 常用用法列舉如下: #### 按級別過濾日志 Android 的日志分為如下幾個優先級(priority): * V —— Verbose(最低,輸出得最多) * D —— Debug * I —— Info * W —— Warning * E —— Error * F —— Fatal * S —— Silent(最高,啥也不輸出) 按某級別過濾日志則會將該級別及以上的日志輸出。 比如,命令: ```sh adb logcat *:W ``` 會將 Warning、Error、Fatal 和 Silent 日志輸出。 (**注:** 在 macOS 下需要給 `*:W` 這樣以 `*` 作為 tag 的參數加雙引號,如 `adb logcat "*:W"`,不然會報錯 `no matches found: *:W`。) #### 按 tag 和級別過濾日志 `<filter-spec>` 可以由多個 `<tag>[:priority]` 組成。 比如,命令: ```sh adb logcat ActivityManager:I MyApp:D *:S ``` 表示輸出 tag `ActivityManager` 的 Info 以上級別日志,輸出 tag `MyApp` 的 Debug 以上級別日志,及其它 tag 的 Silent 級別日志(即屏蔽其它 tag 日志)。 #### 日志格式 可以用 `adb logcat -v <format>` 選項指定日志輸出格式。 日志支持按以下幾種 `<format>`: * brief 默認格式。格式為: ```sh <priority>/<tag>(<pid>): <message> ``` 示例: ```sh D/HeadsetStateMachine( 1785): Disconnected process message: 10, size: 0 ``` * process 格式為: ```sh <priority>(<pid>) <message> ``` 示例: ```sh D( 1785) Disconnected process message: 10, size: 0 (HeadsetStateMachine) ``` * tag 格式為: ```sh <priority>/<tag>: <message> ``` 示例: ```sh D/HeadsetStateMachine: Disconnected process message: 10, size: 0 ``` * raw 格式為: ```sh <message> ``` 示例: ```sh Disconnected process message: 10, size: 0 ``` * time 格式為: ```sh <datetime> <priority>/<tag>(<pid>): <message> ``` 示例: ```sh 08-28 22:39:39.974 D/HeadsetStateMachine( 1785): Disconnected process message: 10, size: 0 ``` * threadtime 格式為: ```sh <datetime> <pid> <tid> <priority> <tag>: <message> ``` 示例: ```sh 08-28 22:39:39.974 1785 1832 D HeadsetStateMachine: Disconnected process message: 10, size: 0 ``` * long 格式為: ```sh [ <datetime> <pid>:<tid> <priority>/<tag> ] <message> ``` 示例: ```sh [ 08-28 22:39:39.974 1785: 1832 D/HeadsetStateMachine ] Disconnected process message: 10, size: 0 ``` 指定格式可與上面的過濾同時使用。比如: ```sh adb logcat -v long ActivityManager:I *:S ``` #### 清空日志 ```sh adb logcat -c ``` ### 內核日志 命令: ```sh adb shell dmesg ``` 輸出示例: ```sh <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` 那一行前面的時間就是。 ## 查看設備信息 ### 型號 命令: ```sh adb shell getprop ro.product.model ``` 輸出示例: ```sh Nexus 5 ``` ### 電池狀況 命令: ```sh adb shell dumpsys battery ``` 輸入示例: ```sh 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% 的電量。 ### 屏幕分辨率 命令: ```sh adb shell wm size ``` 輸出示例: ```sh Physical size: 1080x1920 ``` 該設備屏幕分辨率為 1080px * 1920px。 如果使用命令修改過,那輸出可能是: ```sh Physical size: 1080x1920 Override size: 480x1024 ``` 表明設備的屏幕分辨率原本是 1080px * 1920px,當前被修改為 480px * 1024px。 ### 屏幕密度 命令: ```sh adb shell wm density ``` 輸出示例: ```sh Physical density: 420 ``` 該設備屏幕密度為 420dpi。 如果使用命令修改過,那輸出可能是: ```sh Physical density: 480 Override density: 160 ``` 表明設備的屏幕密度原來是 480dpi,當前被修改為 160dpi。 ### 顯示屏參數 命令: ```sh adb shell dumpsys window displays ``` 輸出示例: ```sh 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。 ### android\_id 命令: ```sh adb shell settings get secure android_id ``` 輸出示例: ```sh 51b6be48bac8c569 ``` ### IMEI 在 Android 4.4 及以下版本可通過如下命令獲取 IMEI: ```sh adb shell dumpsys iphonesubinfo ``` 輸出示例: ```sh Phone Subscriber Info: Phone Type = GSM Device ID = 860955027785041 ``` 其中的 `Device ID` 就是 IMEI。 而在 Android 5.0 及以上版本里這個命令輸出為空,得通過其它方式獲取了(需要 root 權限): ```sh adb shell su service call iphonesubinfo 1 ``` 輸出示例: ```sh 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](http://stackoverflow.com/questions/27002663/adb-shell-dumpsys-iphonesubinfo-not-working-since-android-5-0-lollipop) ### Android 系統版本 命令: ```sh adb shell getprop ro.build.version.release ``` 輸出示例: ```sh 5.0.2 ``` ### IP 地址 每次想知道設備的 IP 地址的時候都得「設置」-「關于手機」-「狀態信息」-「IP地址」很煩對不對?通過 adb 可以方便地查看。 命令: ```sh adb shell ifconfig | grep Mask ``` 輸出示例: ```sh 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: ```sh adb shell ifconfig wlan0 ``` 輸出示例: ```sh wlan0: ip 10.129.160.99 mask 255.255.240.0 flags [up broadcast running multicast] ``` 或 ```sh 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 ``` 如果以上命令仍然不能得到期望的信息,那可以試試以下命令(部分系統版本里可用): ```sh adb shell netcfg ``` 輸出示例: ```sh 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 地址 命令: ```sh adb shell cat /sys/class/net/wlan0/address ``` 輸出示例: ```sh f8:a9:d0:17:42:4d ``` 這查看的是局域網 Mac 地址,移動網絡或其它連接的信息可以通過前面的小節「IP 地址」里提到的 `adb shell netcfg` 命令來查看。 ### CPU 信息 命令: ```sh adb shell cat /proc/cpuinfo ``` 輸出示例: ```sh Processor : ARMv7 Processor rev 0 (v7l) processor : 0 BogoMIPS : 38.40 processor : 1 BogoMIPS : 38.40 processor : 2 BogoMIPS : 38.40 processor : 3 BogoMIPS : 38.40 Features : 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 : 0 Hardware : 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)`。 ### 內存信息 命令: ```sh adb shell cat /proc/meminfo ``` 輸出示例: ```sh 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` 是當前空閑內存。 ### 更多硬件與系統屬性 設備的更多硬件與系統屬性可以通過如下命令查看: ```sh 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` 屬性名查找不到,可以這樣試試: ```sh adb shell cat /system/build.prop | grep ro.product.cpu.abi ``` 示例輸出: ```sh ro.product.cpu.abi=armeabi-v7a ro.product.cpu.abi2=armeabi ``` ## 修改設置 **注:** 修改設置之后,運行恢復命令有可能顯示仍然不太正常,可以運行 `adb reboot` 重啟設備,或手動重啟。 修改設置的原理主要是通過 settings 命令修改 /data/data/com.android.providers.settings/databases/settings.db 里存放的設置值。 ### 分辨率 命令: ```sh adb shell wm size 480x1024 ``` 表示將分辨率修改為 480px * 1024px。 恢復原分辨率命令: ```sh adb shell wm size reset ``` ### 屏幕密度 命令: ```sh adb shell wm density 160 ``` 表示將屏幕密度修改為 160dpi。 恢復原屏幕密度命令: ```sh adb shell wm density reset ``` ### 顯示區域 命令: ```sh adb shell wm overscan 0,0,0,200 ``` 四個數字分別表示距離左、上、右、下邊緣的留白像素,以上命令表示將屏幕底部 200px 留白。 恢復原顯示區域命令: ```sh adb shell wm overscan reset ``` ### 關閉 USB 調試模式 命令: ```sh adb shell settings put global adb_enabled 0 ``` 恢復: 用命令恢復不了了,畢竟關閉了 USB 調試 adb 就連接不上 Android 設備了。 去設備上手動恢復吧:「設置」-「開發者選項」-「Android 調試」。 ### 狀態欄和導航欄的顯示隱藏 本節所說的相關設置對應 Cyanogenmod 里的「擴展桌面」。 命令: ```sh adb shell settings put global policy_control <key-values> ``` `<key-values>` 可由如下幾種鍵及其對應的值組成,格式為 `<key1>=<value1>:<key2>=<value2>`。 | key | 含義 | |-----------------------|------------| | immersive.full | 同時隱藏 | | immersive.status | 隱藏狀態欄 | | immersive.navigation | 隱藏導航欄 | | immersive.preconfirms | ? | 這些鍵對應的值可則如下值用逗號組合: | value | 含義 | |----------------|--------------| | `apps` | 所有應用 | | `*` | 所有界面 | | `packagename` | 指定應用 | | `-packagename` | 排除指定應用 | 例如: ```sh adb shell settings put global policy_control immersive.full=* ``` 表示設置在所有界面下都同時隱藏狀態欄和導航欄。 ```sh adb shell settings put global policy_control immersive.status=com.package1,com.package2:immersive.navigation=apps,-com.package3 ``` 表示設置在包名為 `com.package1` 和 `com.package2` 的應用里隱藏狀態欄,在除了包名為 `com.package3` 的所有應用里隱藏導航欄。 ## 實用功能 ### 屏幕截圖 截圖保存到電腦: ```sh adb exec-out screencap -p > sc.png ``` 如果 adb 版本較老,無法使用 `exec-out` 命令,這時候建議更新 adb 版本。無法更新的話可以使用以下麻煩點的辦法: 先截圖保存到設備里: ```sh adb shell screencap -p /sdcard/sc.png ``` 然后將 png 文件導出到電腦: ```sh adb pull /sdcard/sc.png ``` 可以使用 `adb shell screencap -h` 查看 `screencap` 命令的幫助信息,下面是兩個有意義的參數及含義: | 參數 | 含義 | |---------------|--------------------------------------------| | -p | 指定保存文件為 png 格式 | | -d display-id | 指定截圖的顯示屏編號(有多顯示屏的情況下) | 實測如果指定文件名以 `.png` 結尾時可以省略 -p 參數;否則需要使用 -p 參數。如果不指定文件名,截圖文件的內容將直接輸出到 stdout。 另外一種一行命令截圖并保存到電腦的方法: *Linux 和 Windows* ```sh adb shell screencap -p | sed "s/\r$//" > sc.png ``` *Mac OS X* ```sh adb shell screencap -p | gsed "s/\r$//" > sc.png ``` 這個方法需要用到 gnu sed 命令,在 Linux 下直接就有,在 Windows 下 Git 安裝目錄的 bin 文件夾下也有。如果確實找不到該命令,可以下載 [sed for Windows](http://gnuwin32.sourceforge.net/packages/sed.htm) 并將 sed.exe 所在文件夾添加到 PATH 環境變量里。 而在 Mac 下使用系統自帶的 sed 命令會報錯: ```sh sed: RE error: illegal byte sequence ``` 需要安裝 gnu-sed,然后使用 gsed 命令: ```sh brew install gnu-sed ``` ### 錄制屏幕 錄制屏幕以 mp4 格式保存到 /sdcard: ```sh adb shell screenrecord /sdcard/filename.mp4 ``` 需要停止時按 <kbd>Ctrl-C</kbd>,默認錄制時間和最長錄制時間都是 180 秒。 如果需要導出到電腦: ```sh 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 進行寫操作,所以需要重新掛載它為可讀寫。 步驟: 1. 進入 shell 并切換到 root 用戶權限。 命令: ```sh adb shell su ``` 2. 查看當前分區掛載情況。 命令: ```sh mount ``` 輸出示例: ```sh 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 的那一行: ```sh /dev/block/platform/msm_sdcc.1/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0 ``` 3. 重新掛載。 命令: ```sh 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 權限。** 命令: ```sh adb shell su cat /data/misc/wifi/*.conf ``` 輸出示例: ```sh 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 權限。** 命令: ```sh adb shell su date -s 20160823.131500 ``` 表示將系統日期和時間更改為 2016 年 08 月 23 日 13 點 15 分 00 秒。 ### 重啟手機 命令: ```sh adb reboot ``` ### 檢測設備是否已 root 命令: ```sh adb shell su ``` 此時命令行提示符是 `$` 則表示沒有 root 權限,是 `#` 則表示已 root。 ### 使用 Monkey 進行壓力測試 Monkey 可以生成偽隨機用戶事件來模擬單擊、觸摸、手勢等操作,可以對正在開發中的程序進行隨機壓力測試。 簡單用法: ```sh adb shell monkey -p <packagename> -v 500 ``` 表示向 `<packagename>` 指定的應用程序發送 500 個偽隨機事件。 Monkey 的詳細用法參考 [官方文檔](https://developer.android.com/studio/test/monkey.html)。 ### 開啟/關閉 WiFi **注:需要 root 權限。** 有時需要控制設備的 WiFi 狀態,可以用以下指令完成。 開啟 WiFi: ```sh adb root adb shell svc wifi enable ``` 關閉 WiFi: ```sh adb root adb shell svc wifi disable ``` 若執行成功,輸出為空;若未取得 root 權限執行此命令,將執行失敗,輸出 `Killed`。 ## 刷機相關命令 ### 重啟到 Recovery 模式 命令: ```sh adb reboot recovery ``` ### 從 Recovery 重啟到 Android 命令: ```sh adb reboot ``` ### 重啟到 Fastboot 模式 命令: ```sh adb reboot bootloader ``` ### 通過 sideload 更新系統 如果我們下載了 Android 設備對應的系統更新包到電腦上,那么也可以通過 adb 來完成更新。 以 Recovery 模式下更新為例: 1. 重啟到 Recovery 模式。 命令: ```sh adb reboot recovery ``` 2. 在設備的 Recovery 界面上操作進入 `Apply update`-`Apply from ADB`。 注:不同的 Recovery 菜單可能與此有差異,有的是一級菜單就有 `Apply update from ADB`。 3. 通過 adb 上傳和更新系統。 命令: ```sh adb sideload <path-to-update.zip> ``` ## 安全相關命令 ### 啟用/禁用 SELinux 啟用 SELinux ```sh adb root adb shell setenforce 1 ``` 禁用 SELinux ```sh adb root adb shell setenforce 0 ``` ### 啟用/禁用 dm_verity 啟用 dm_verity ```sh adb root adb enable-verity ``` 禁用 dm_verity ```sh adb root adb disable-verity ``` ## 更多 adb shell 命令 Android 系統是基于 Linux 內核的,所以 Linux 里的很多命令在 Android 里也有相同或類似的實現,在 `adb shell` 里可以調用。本文檔前面的部分內容已經用到了 `adb shell` 命令。 ### 查看進程 命令: ```sh adb shell ps ``` 輸出示例: ```sh 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 | 進程名 | ### 查看實時資源占用情況 命令: ```sh adb shell top ``` 輸出示例: ```sh 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 | 優先級 | | CPU% | 當前瞬間占用 CPU 百分比 | | S | 進程狀態(R=運行,S=睡眠,T=跟蹤/停止,Z=僵尸進程) | | #THR | 線程數 | | VSS | Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存) | | RSS | Resident Set Size 實際使用物理內存(包含共享庫占用的內存) | | PCY | 調度策略優先級,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 顯示幫助文檔 ``` ### 查看進程 UID 有兩種方案: 1. `adb shell dumpsys package <packagename> | grep userId=` 如: ```sh $ adb shell dumpsys package org.mazhuang.guanggoo | grep userId= userId=10394 ``` 2. 通過 ps 命令找到對應進程的 pid 之后 `adb shell cat /proc/<pid>/status | grep Uid` 如: ```sh $ 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 失敗 **出錯提示** ```sh error: protocol fault (couldn't read status): No error ``` **可能原因** adb server 進程想使用的 5037 端口被占用。 **解決方案** 找到占用 5037 端口的進程,然后終止它。以 Windows 下為例: ```sh netstat -ano | findstr LISTENING ... TCP 0.0.0.0:5037 0.0.0.0:0 LISTENING 1548 ... ``` 這里 1548 即為進程 ID,用命令結束該進程: ```sh 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](https://github.com/facebook/fb-adb) - A better shell for Android devices (for Mac). ## 致謝 感謝朋友們無私的分享與補充(排名不分先后)。 [zxning](https://github.com/zxning),[linhua55](https://github.com/linhua55),[codeskyblue](https://github.com/codeskyblue),[seasonyuu](https://github.com/seasonyuu),[fan123199](https://github.com/fan123199),[zhEdward](https://github.com/zhEdward),[0x8BADFOOD](https://github.com/0x8BADFOOD),[keith666666](https://github.com/keith666666),[shawnlinboy](https://github.com/shawnlinboy)。 ## 參考鏈接 * [Android Debug Bridge](https://developer.android.com/studio/command-line/adb.html) * [ADB Shell Commands](https://developer.android.com/studio/command-line/shell.html) * [logcat Command-line Tool](https://developer.android.com/studio/command-line/logcat.html) * [Android ADB命令大全](http://zmywly8866.github.io/2015/01/24/all-adb-command.html) * [adb 命令行的使用記錄](https://github.com/ZQiang94/StudyRecords/blob/master/other/src/main/java/com/other/adb%20%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AE%B0%E5%BD%95.md) * [Android ADB命令大全(通過ADB命令查看wifi密碼、MAC地址、設備信息、操作文件、查看文件、日志信息、卸載、啟動和安裝APK等)](http://www.jianshu.com/p/860bc2bf1a6a) * [那些做Android開發必須知道的ADB命令](http://yifeiyuan.me/2016/06/30/ADB%E5%91%BD%E4%BB%A4%E6%95%B4%E7%90%86/) * [adb shell top](http://blog.csdn.net/kittyboy0001/article/details/38562515) * [像高手一樣使用ADB命令行(2)](http://cabins.github.io/2016/03/25/UseAdbLikeAPro-2/) [1]: #ip-地址 --- #### 參考文檔 * [Awesome Adb——一份超全超詳細的 ADB 用法大全](https://juejin.im/entry/57c00fe4c4c971006179838a) * [Awesome Adb存檔](https://github.com/mzlogin/awesome-adb)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看