--- 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
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.