--- title: 'ADB 基礎' disqus: kyleAlien --- ADB 基礎 === ## OverView of Content ```shell= # adb 基本指令格式 adb [-d|-e|-s <serialNumber>] <command> ``` [TOC] ## ADB 概述 全名是 Android Debug Bridge (ADB),可以用命令行與設備進行通訊,ADB 工具在 <android_sdk\>/platform-tools/ 資料夾下,或 [**單獨下載**](https://developer.android.com/studio/releases/platform-tools) 該工具 >  ### 工作原理 * **++服務器 (電腦)++ 在啟動時會與本地 TCP 端口 ==5037== 綁定**,所有 adb 客戶端均通過端口 5037 與 adb 服務器通訊 > Window 使用 cmd 並輸入 `netstat` 就可以獲得所有網路 Port,當然也可以指定 5037 `netstat -ano | findstr 5037` >  * 服務器會與所有正在運行的設備建立連接,它會掃描 5555 ~ 5585 之間的基數號端口(eg. 5555、5557、5559...) 總共可以有 16 個裝置,服務器一旦發現手機的 adb 守護程序 (adbd),便會與該端口進行連接 * 每個模擬器都會使用一對按照順序排列的端口 1. 偶數:控制台連接的端口 2. 奇數:adb 連接的端口 >  * 以下來判斷 5037 Port 到底被誰占用 (Window 系統),使用到指令 ^1^netstat、^2^tasklist、^3^findstr >  ## 基礎命令 ### adb 版本 * 可以查出 adb 版本 & 該指令安裝的位置 ```shell= adb version ``` >  ### 啟動/停止 adb 服務 1. 啟動 ```shell= adb start-server ``` >  2. 停止 ```shell= adb kill-server ``` >  3. 重新連接裝置 (下面小節會說明 connect) ```shell= adb reconnect # 也可以指定重連接的 device adb reconnect ca6b55ed ``` >  ## 設備 adb 調適 * 在 Android 4.2 及更高版本的設備上,**開發者選項默認是隱藏狀態**,需要轉到`設置手機` -> `關於手機` 接著按版本號 7 次 * 之後進入 `開發人員選項` 中,並開啟 **==USB偵錯==** >  ```shell= # 基礎使用,查看裝置是否有被 adb 連接 adb devices ``` >  | 狀態欄位(依序) | 說明 | | -------- | -------- | | 序列號 | adb 所創建的字符串,用於通過端口號唯一設備裝置,**之後會透過該序列號傳送指令** | | 狀態 | 有三種狀態 ^1^ offline:設備未連接到 adb or 沒響應、^2^device:設備以連接到服務器、^3^no device:尚未連接任何設備 | | 說明 | 需要添加參數 `-l`,這會說明該設備產品名、模組等等 | * 添加 l 參數可以清楚看到目前是哪個裝置被連接,它的產品名、模組等等 ```shell= # 裝置的詳細訊息 adb devices -l ``` >  ### 無線連線 | 使用指令 & 格式 | 說明 | | -------- | -------- | | tcpip <PORT_NUM\> | 連線 PORT 號設定 | | connect HOST[:PORT] | 透過 TCP/IP 連線設備 (PORT 預設為 5555) | | disconnect [HOST[:PORT]] | 斷開 TCP/IP 連線,若未設定則全部斷開 | 0. 在 Android 裝置中設定開發人員選項,**開啟 `無線偵錯` 開關** 1. 將 Android 裝置與執行 adb 的服務端(PC) 連線到同一個網域(eg. 同一個 WIFI) 2. 使用 USB 將 Android 裝置與電腦連線,並開啟 USB 偵測模式,使用 `adb devices` 查看 >  3. 設定 adbd 監聽的 PORT 號 ```shell= # 設定 adbd 監聽 Port 為 5555 adb tcpip 5555 ``` >  4. 斷開 USB 5. 去手機中找 `IP 位置` 並記錄下來 (通常在 設定 -> 網路設定 or WIFI 裡面) 6. 通過 剛剛紀錄的 IP 位置與連線裝置 (或斷開) ```shell= # 連線 adb connect 192.168.1.101:5555 # 斷開 adb disconnect 192.169.1.101:5555 ``` 7. 確認連線狀態 ```shell= adb devices ``` >  :::info * 若尚未連線就使用 kill-server 重新啟動 adb 重試試 ::: ### 有線連線 | 使用指令 | 指令格式 | | -------- | -------- | | usb | 重新設定 adbd 的連線 | ```shell= adb usb ``` >  ### 指定 adb server port * ADB Port 號預設為 5037,但也可以自己指定 ```shell= # 指令格式 adb -P <port_num> start-server ``` ```shell= # 停止當前 adb 服務 adb kill-server # 連接指定 Port 號 adb -P 8888 start-server # 找 window 當前對應的 prot 號 netstat -ano | findstr 8888 # 找到該 port 號使用的應用程式 tasklist | findstr 19704 ``` >  ### 模擬器未被列出 // TODO: 參考官方 ## 發送命令 * 若需要對設備發送命令的話,就必須指定你要發送命令的序列號,該序列號可以透過 adb devices 獲得 設備連接指令 | adb options | 解釋 | | -------- | -------- | | -s | 指定序列號(須查詢) | | -e | **若只有一個模擬器,可以直接用 -e 安裝** (多個模擬器則必須指定) | | -d | **若只有一個實體裝置,可以直接用 -d 安裝** (多個實體裝置則必須指定) | ```shell= // 查看序列號 adb devices -l // 指定序列號 -s adb -s R58N70X9XFX shell dumpsys activity | findstr mResume ``` >  ### 安裝 APK install * 使用關鍵字 **install** 安裝 APK 到設備,以下說明幾個較常使用的 options (配合 install 使用) ```shell= # 指令格式 adb <連接設備方式> install [options] <APK_PATH> ``` | options | 說明 | | -------- | -------- | | -r | 允許覆蓋已有的 APP 應用 | | -t | 允許安裝測試 APP,該測試 APP 必須在 AndroidManifest.xml#application 中設置,**android:testOnly="true"** | | -d | 允許安裝版本低的 APP (一般來說裝置上的 version code = 11,就不能安裝 version code 是 10 的應用) | | -s | 安裝 APK 到 SDK card 中 | | -g | 授權 Runtime 時所需的權限 (eg. 外部儲存、位置...) | * 安裝 APP,使用 -r 覆蓋,並且使用 -d 允與安裝較低版本的 APP ```shell= # 目前我使用實體機,而且只有一台,所以直接使用 -d 安裝 adb -d install -r -d C:\Users\alien\StudioProjects\MyApp\app\build\outputs\apk\prodUniversal\release\ReleaseApp.apk ``` >  :::warning * 以下狀況是裝置上的 version 比起目前要安裝的App version 還要高所以無法安裝,這時候只要使用 `-d` 就可以安裝 APP ```shell= adb -d install -r C:\Users\alien\StudioProjects\MyApp\app\build\outputs\apk\prodUniversal\release\ReleaseApp.apk ``` >  ::: * 安裝錯誤提示,**詳細的可以參考 PackageManager** | 錯誤內容 | 說明 | 解法 | | -------- | -------- | -------- | | `INSTALL_FAILED_ALREADY_EXISTS` | 應用已經存在 | -r | | `INSTALL_FAILED_INVALID_APK` | 無效的 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` | 已經安裝過簽名不一樣的同名應用,且資料沒有移除 | | | `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 引數 | -t | | `INSTALL_FAILED_CPU_ABI_INCOMPATIBLE` | 包含不相容裝置 CPU 應用程式二進位制介面的 native code | | | `INSTALL_FAILED_MISSING_FEATURE` | 應用使用了裝置不可用的功能 | | | `INSTALL_FAILED_CONTAINER_ERROR` | sdcard 訪問失敗 | 確認 sdcard 可用,或者安裝到內建儲存 | | `INSTALL_FAILED_INVALID_INSTALL_LOCATION` | 不能安裝到指定位置 | 切換安裝位置,新增或刪除 **-s** 引數 | | `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、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 devicerm | 空間不足 | 清理空間 | | Permission denied … sdcard … | sdcard 不可用 | | ### 解除安裝 uninstall * 使用關鍵字 uninstall 卸載指定應用 ```shell= # 指令格式 adb uninstall [options] <PACKAGE_NAME> ``` | options | 說明 | | -------- | -------- | | -k | 保留應用的 data & cache 資料夾 | 解除 flutter_hello_world 應用 ```shell= adb uninstall com.demo.flutter_hello_world ``` >  ### 傳送/接收檔案 push / pull | 指令關鍵字 | 說明 | | -------- | -------- | | push [Options] <file_name\> | 複製檔案到手機中 | | pull [Options] <file_name\> | 把檔案從手機拉到 PC | >  | Options | 說明 | | -------- | -------- | | -p | 顯示傳輸進度 | | -a | 拷貝時保留時間搓 & 模式,相當於 Linux 中 cp -p 的 options | :::info * Linux 中可以使用 `man cp` 的指令查找 cp 到相關 options >  ::: 1. push ```shell= # 複製圖片到手機 push adb push C:\Users\alien\Pictures\no_problem.png /sdcard/ ``` >  :::info * 如果使用 Android studio 模擬器,該路徑在 `storage/self/primary` 下 ::: 2. pull ```shell= # 從手機裝置中拉下圖片到 桌面 adb pull /sdcard/yoyo.png Desktop/ ``` >  ### logcat 分級 & tag 分類 | 級別 | 說明 | | -------- | -------- | | V \ Verbose | 全都輸出 | | D \ Debug | | | I \ Info | | | W \ Warning | | | E \ Error | | | F \ Fatal | | | S \ Silent | 都不輸出 | 指令格式 ```shell= # 指令格式,Level 是指定輸出的 Logcat 級別 adb logcat *:<Level> # 輸出 Error tag adb logcat *:E ``` 指定 tag 輸出 ```shell= # 輸出 Tag 為 LobbyActivity & LaunchActivity Debug 級別以上的日誌,其他的都不輸出 adb logcat LobbyActivity:D LaunchActivity:D *:S ``` ### locat 日誌格式 ```shell= # 指令格式 adb logcat [options] [filterspecs] ``` * 詳細的使用可以用 `adb locat --help` 查詢 (需要連接手機 or 開啟模擬器),大部分拿來查看 crash 問題 | 通用 Options | 說明 | | -------- | -------- | | -f <file\> | 將日誌輸出到檔案中 (測試失敗) | | -b/ --buffer=<buffer\> | 備用環形緩衝區,**允許多個 -b 參數或逗號分隔緩衝區列表**,默認 -b 為 ^1^main、^2^system、^3^crash、^4^kernal | | -L/ --last | 彈出所有 **pstore(下面說明)** 的 logcat | | -c/ --clear | 清除 logcat 訊息 | | -d | 輸出日誌並不堵塞 | | -t <count\> | 輸出最近日誌,並且可以指定數量,可以配合 `-d` 使用 | | -T <time\> | 指定時間到當前時間的日誌,時間格式 | | -B/ --binary | 二進位的方式輸出日誌`'MM-DD hh:mm:ss.mmm...`、`YYYY-MM-DD hh:mm:ss.mmm...`、`sssss.mmm...` | | -g | 輸出 Buffer size | | -v <format\> | 指定輸出的格式,**==只能指定一種格式==** | :::info * What is [**pstore**](http://huaqianlee.github.io/2020/11/13/Android/pstore/) ? > pstore 又稱為 persistent storage,這是一個儲存內核日誌 & 內核 panic 文件系統,內核會把相關信息儲存,**在一個不能被其他用戶重寫的 RAM 區** > 下次啟動時,這個區域會被掛載到 `pstore`,一般在 `/sys/fs/pstore` 這樣我們才可以訪問這些數據 ::: * 若有多個裝置則必須使用 -s 指定裝置,下面的範例都只有一台測試,所以沒有指定 1. 緩衝區指定 -b ```shell= # 以下指定三個緩衝區 crash、system、kernel adb logcat -b crash -b system -b kernel ``` >  2. 指定日誌輸出數量 ```shell= # 輸出最近 10 筆日誌 adb logcat -t 10 ``` >  3. 查看 Buffer 大小 ```shell= # 可以看到 system、main、crash buffer size adb logcat -g ``` >  4. -v options 介紹 | Column 1 | Column 2 | | -------- | -------- | | brief | 顯示 priority/tag、pid、message | | long | 顯示所有元數據(metadata field),並且 message 換行 | | process | 只顯示 PID | | raw | 輸出數據原型,並且沒有 metadata field | | tag | 只顯示 priority/tag | | thread | 顯示 PID and TID 訊息 | | threadtime | 顯示 調用時間、PID、TID、Date time | | time | 調用時間、priority/tag、PID | ```shell= # 指定 PID adb logcat -t 10 -v process ``` >  ## [Shell](https://developer.android.com/studio/command-line/adb#shellcommands) 指令 ```shell= # shell 基礎格式 adb [-d |-e | -s serial_number] shell shell_command # 直接進行 shell 交互,使用 `Crtl + D` 結束戶交 adb [-d |-e | -s serial_number] shell # 查看所有 Unix 指令 adb shell ls /system/bin/ ``` * 幾個較常使用的 shell command 如下 | shell command | 功能 | | -------- | -------- | | am | Activity 管理器 | | pm | Package 管理器 | | dumpsys | 調出系統資訊 | | wn | Window 管理器 | | settings | 手機設定的資訊 | :::info * 大部分命令都是由 [**toyBox**](http://landley.net/toybox/) 提通,可以透過命令查看 toybox 的所有命令 ```shell= toybox --help ``` ::: ### Activity 管理器 [am](https://developer.android.com/studio/command-line/adb#am) * 可以用來啟動 Activity、強行停止進程、廣播 intent、修改設備螢幕屬性等等功能 ```shell= # 指令格式 adb shell am <command> ``` | Command | 功能 | | -------- | -------- | | start [options] <Intent\> | 啟動指定的 Activity | | start-services [options] <Intent\> | 啟動指定的 | | broadcast [options] <Intent\> | 傳送指定的廣播 | | force-stop <packagename\> | 停止 Package 相關應用 | | kill [options] <package\> | 終止與 package 相關的所有進程,與 force-stop 不同在於,該命令可以安全的停止應用而不影響用戶體驗 | | kill-all | 終止所有後台進程 | * start intent options | intent options | 功能 | 範例 | | -------- | -------- | -------- | | -a <ACTION\> | 指定 Action | android.intent.action.VIEW | | -c <CATEGORY\> | 指定 Category | android.intent.category.APP_CONTACTS | | -n <COMPONENT\> | 指定完整 component 名,明確指出要啟動哪個 Activity | com.example.app.\ExampleActivity | 1. 啟動 intent VIEW ```shell= adb shell am start -a android.intent.action.VIEW ``` >  | 帶 Bundle 參數 | 說明 | | -------- | -------- | | --esn <EXTRA_KEY> | null 值(只有 key 名) | | –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 array | | --ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...] | long array | 2. 使用 adb 指令開啟 APP ```shell= # adb 啟動 <Pack name> / <Launch activity> adb -e shell am start -n com.test.example/.activity.LobbyActivity # 也可以使用 start-activity 啟動 Activity adb -e shell am start-activity com.test.example/.activity.LobbyActivity ``` > IDE 替我們執行的指令 (範例) >  :::warning * 要啟動的 Activity 必須有宣告 intent-filter 為 LAUNCH,否則不能啟動,並且會拋出錯誤 ```xml= <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> ``` >  ::: ### 應用管理 pm * pm 可以記憶成 Package Manager ```shell= # 指令格式 adb shell pm <Command> [options] # 若是沒有 options 則會列出所有應用 adb shell pm list packages [options] ``` * 較常使用的 pm's command | pm's command | 功能 | | -------- | -------- | | list package | 可列出所有的 package,**查看相關指令要到 `adb shell cmd package`** | | dump <package_name> | 與該 package 相關的訊息(啟動 Activity & 權限 & meminfo 等等資訊...) | | path <package_name> | **該 APP 安裝路徑** | | install <package_name> | 安裝 APP | | uninstall <package_name> | 解除 APP | | enable <package_name> | 啟用 APP | | disable <package_name> | 禁用 APP,**同時會隱藏 APP** | | hide <package_name> | 隱藏 APP (測試失敗...?) | | grant <package_name> <permission_item> | 同意某個權限 | | revoke <package_name> <permission_item> | 撤銷某個權限 | | reset-permissions <package_name> | **應用的權限 reset**,若沒有指定包名,則全部應用 reset | | clear <package_name> | 清除所有 App 儲存的資料 | ```shell= adb shell pm reset-permissions # 查看安裝路徑 adb shell pm path tw.com.alien.www.bluetooth_le ``` >  * 較常使用的 list's packages options | list's packages options | 功能 | | -------- | -------- | | -f | 顯示應用關聯的 apk 檔案 (A 應用 與 B 應用的差異) | | -d (disable) | 顯示無法使用的應用 | | -e (enable) | 顯示可使用的應用 | | -s (system) | 系統應用 | | -3 (thired) | 第三方應用 (自己開發的應用就算是一個) | | -i (installer) | 該應用的安裝者 | | -u | 顯示當前有的應用程式,包括之前已解除安裝的應用 | | <filter\> | 也可輸入相關字串查詢應用 | 1. -d 無法使用的應用 >  2. -s 查看系統應用 >  3. 輸入相關字串查詢應用 ```shell= # 查找 vivo 相關應用 adb shell pm list packages vivo ``` >  * 可以使用 `findstr (Window)`、`grep (Linux)` 鎖定命標應用 ```shell= adb shell pm list packages | findstr android ``` >  ### 系統訊息 dumpsys * dumpsys 可以調用出許多資料,在優化程式時也可以調出許多數據 ```shell= # 查詢 shell dumpsys 使用 adb -d shell dumpsys --help # 查詢指定 command 使用 ``` | Command | 功能 | | -------- | -------- | | <options\> | | | cpuinfo | 當前 CPU 訊息,`adb shell cat /proc/cpuinfo` 可以查看 CPU 型號 | | memory | 當前記憶體狀態 & 使用量 (包含 PID) | | package | 顯示 package 包名 | | battery <options\> | 電池資訊 | | window <options\> | 屏幕資訊 | | status | 狀態欄訊息 | | alarm | 警告訊息 | 1. 電池資訊 battery ```shell= adb -d shell dumpsys battery ``` >  2. 屏幕引數 ```shell= adb -d shell dumpsys window displays ``` 下圖的資訊 a. init:1080 x 2400 420dpi 是螢幕初始解析度 & 密度 b. app:1080 x 2274 高度稍微比 init 小 c. 虛擬按鍵:2400 - 2274 = 126px >  ### 螢幕訊息 wm ```shell= # 查詢 shell wm 使用 adb -d shell wm help ``` | Options | 功能 | | -------- | -------- | | size | 螢幕大小,其單位是 **pixels** | | density | 密度,其單位是 **dpi**,算法可以參考 [**螢幕兼容**](https://hackmd.io/tVarTmeBSOO9YBT-PbcAzA?view) | 1. 螢幕 Size ```shell= # 絕對單位 px adb -d shell wm size ``` >  2. 螢幕密度 (DPI) ```shell= # dpi 像素密度 adb -d shell wm density ``` >  :::info * 計算出螢幕 Inch ```shell= # dpi = pixels / inch inch = 2400 / 420 Ans. 5.71 (inch) ``` ::: ### [Android id](https://oldgrayduck.blogspot.com/2017/08/androidandroidid-android.html) * Android ID 代表了該 Android 裝置唯一值,在手機第一次開機時就已經設定完成 (**恢復原廠設定時又會再次更改**),若需要判斷唯一值時,相當好判別 ```java= // Java 可以這樣取得設定 Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID) ``` * 使用 adb 取得 Android id ```shell= adb -d shell settings get secure android_id ``` ### 系統訊息 - 其他 * 大部分都是使用 Linux cat 命令去遊覽系統資訊,所以需要對 Linux 系統較孰悉,有興趣可以參考 [**Linux 基礎**](https://hackmd.io/MtOap5UaR7KcJpdTisc75g?view) 1. CPU 資訊 ```shell= # proc 目錄是系統映射 adb shell cat /proc/cpuinfo ``` 2. 硬體訊息,存在 sys 目錄下 (瀏覽該目錄必須要 root 裝置) ### Bugreport * Bugreport 是 Android 系統自帶的日誌分析系統,它包含系統的啟動 Log,以及詳細的進程資訊、VM、Cacahe、Memory 等等訊息,對於上層 APP 作用較小,大致上理解就可以 ```shell= # 指令格式 adb bugreport <輸出檔案名稱> ``` >  ## 實用功能 ### 螢幕節圖 screencap ```shell= # 截圖指令格式 adb -d shell screencap <options> # 詳細使用方法 adb shell screencap --help ``` | Options | 說明 | | -------- | -------- | | -h | 訊息 (不清楚) | | -p | 以 PNG 儲存圖片 | | -d <display-id\> | 指定截圖的顯示屏編號(default: 0),display-id 可以透過 `dumpsys SurfaceFlinger` 只到合法 ID | 1. 螢幕截圖並移動至桌面 ```shell= # 截圖 adb -d shell screencap -p helloWorld.png # 移動到桌面 adb pull /sdcard/helloWorld.png ./Desktop ``` >  ### 螢幕錄製 screenrecord ```shell= # 錄影指令格式 adb -d shell screenrecord [options] <filename> # 使用方法 adb -d shell screenrecord --h ``` | options | Column 3 | | -------- | -------- | | --size <Width\*Height\> | 設定錄影寬高 | | --bit-rate <\RATE> | 設定錄影的畫素,預設 20Mbps,設定 400000 -> 4M | | --bugreport | 添加其他信息 eg. 時間戳 | | --time-limit <TIME\> | 設定錄影的時間,**==最長 180 秒==**,單位 ms | | -display-id <ID\> | 指定截圖的顯示屏編號(default: 0),display-id 可以透過 `dumpsys SurfaceFlinger` 只到合法 ID | | --verbose | 顯示相關資訊 | ## Appendix & FAQ 目前還沒測試 root 的手機,所以部分目錄無法訪問 :::info ::: ###### tags: `Android 工具`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up