ByteScope

settings get

唯讀

從手機的設定提供者讀出一個值。

指令
adb shell settings get
指令
設定提供者
風險
唯讀

語法

settings get <system|secure|global> <key>

旗標與參數

token意義
system | secure | global這個 key 在哪個命名空間。一共三個、是分開的表,問錯的那個會拿到「沒有」而不是錯誤。

範例

  • settings get global http_proxy

    確認手機有沒有指向某個除錯用的 proxy。

  • settings get global window_animation_scale

    在改之前先讀,這樣你手上才有能還原的值。

  • settings get system show_touches

    一個 `system` 的 key,用來說明命名空間並不總是 `global`。

輸出怎麼讀

輸出範例

null

只有一行:值,或 `null` 這四個字元。`null` 是真正的答案而不是失敗——大多數開發者選項在新手機上根本沒設定過,它們的實際行為來自平台預設值而不是任何被存下來的東西。超過一行的東西不是值,是 shell 併進輸出裡的錯誤。

輸出欄位

欄位意義
<value>存下來的值,以文字形式。
null這個 key 沒有設定,平台預設值生效。
(a stack trace)讀取被拒絕。這不是值。

需要什麼權限

不用 root,也不用 `adb root`。`settings` 只是一行的 shell 腳本,內容是 `cmd settings "$@"`(AOSP 的 `cmds/settings/settings.sh`),所以另一端是用已授權 `adb` 連線的 `shell` 使用者身分來回答這次讀取的。讀取是這一家族權限故事裡明顯便宜的那一半:寫入那邊靠的是 `android.permission.WRITE_SECURE_SETTINGS`,而單純讀一個 `system`、`secure` 或 `global` 的 key,不需要任何 shell 缺少的東西。除了 USB 偵錯本身,這裡沒有東西藏在開發者選項的開關後面。有兩個細節決定你能不能相信一個很短的答案。值是用 `pout.println(...)` 印在 out 串流上的,而參數解析器的每一句抱怨——打錯的命名空間、多出來的一個字——都印在 err 串流上,而且指令會直接回傳 -1、根本沒去讀。把 stderr 丟掉,一次被拒絕的指令就變成一行空白,看起來和「這個 key 沒設定」一模一樣。另外,使用者是在讀取之前先決定的:沒有 `--user` 時,指令會先問 activity manager 目前是哪個使用者,然後讀那個使用者的表——所以一台有工作設定檔的手機,會依照前景是誰,對同一個 `secure` key 給出兩種不同的答案。

失敗訊息對照

訊息意義
Invalid namespace 'globl'第一個位置參數不是 `system`、`secure` 或 `global`。比對不分大小寫,所以 `Global` 沒問題,只有真的打錯才會走到這裡。解析就此停止、指令回傳 -1,所以什麼都沒讀到——這和「key 不存在」不是同一件事,即使兩者都讓你手上沒有值。這一行走 stderr。
Invalid command: gett動詞不是 `get`、`put`、`delete`、`list`、`reset` 之一。把選項擺錯位置也會拿到它,因為解析器預期除了 `--user` 以外,動詞要排在最前面。什麼都沒讀到。
Bad arguments解析器走到指令列尾端,卻始終沒有湊出一個完整的請求——`settings get global` 後面沒給 key 是最常見的原因。它是包山包海的那一種:它不會指名任何東西,所以請重讀整行而不是只看最後一個字。
Too many arguments對 `get` 來說,key 是最後一個被接受的東西,後面再有什麼都直接拒絕。這正是一個含空白又沒加引號的 key 會產生的結果,而這其實是慈悲:另一種下場是它讀了第一個字,然後把它當成答案。
cmd: Can't find service: settings`cmd` 找不到 `settings` 服務可以把子指令交出去,因為 `settings.sh` 只是 `cmd settings` 的包裝。裝置還在開機、`system_server` 還沒登記它的時候,這是預期中的——等開機完成,不要把它當成 key 不存在。

版本與廠商注意事項

  • 命名空間弄錯是無聲的:只是你問的那張表裡沒有這個 key,不會有任何錯誤讓你察覺。
  • 寫之前先讀。平台不會替你記住原本的值,所以想知道要還原成什麼,只有這個指令。

這個我們有 UI

Android ADB Toolbox 會透過 USB 執行這個指令並解析回應——只要 Chromium 系瀏覽器,不必安裝 SDK,也不會上傳任何東西。

開啟 Android ADB Toolbox

相關指令

和 settings get 會在同一次作業裡出現的指令。

指令做什麼
settings put把值寫進設定提供者——多數開發者選項小技巧背後的機制。
getprop印出系統屬性——手機自己對「這是什麼」的回答。
am broadcast送出廣播 intent,這是從 shell 驅動 SystemUI demo mode 等平台接收器的方法。

這些行為是在撰寫 Web ADB 工具背後的解析程式時,對照 AOSP、toybox 與核心原始碼查證的。真的會因 Android 版本或廠牌而異的地方,這一頁會直接說明,而不是給你一個在半數手機上都是錯的數字。

常見問題

adb shell 指令要怎麼執行?

在手機上打開開發者選項與 USB 除錯、接上線,然後從裝了 platform-tools 的機器執行 adb shell <指令>——或者只執行 adb shell 取得互動提示字元,再直接打指令、不用前綴。如果指令會輸出二進位資料(例如截圖),請改用 adb exec-out 而不是 adb shell:單純的 shell 服務會配一個終端機,而它會改寫換行位元組並毀掉資料。

adb shell 指令需要 root 嗎?

這份參考裡的都不用。它們以 shell 使用者身分執行,可以針對自己的 Android 使用者管理套件、讀取大多數 dumpsys 服務、寫入設定提供者、注入輸入,以及讀取共用儲存空間。需要 root 的是這份參考刻意避開的事:讀取其他 app 的私有資料(除了對可除錯版本使用 run-as)、寫入系統分割區,或直接讀 /data/anr。

為什麼在我的手機上輸出看起來不一樣?

不是 Android 版本就是廠商。有些旗標與欄位是從特定版本才有的,那些都在各指令頁註明了。其餘是廠商改動,而受影響最深的是 dumpsys:一份 dump 是除錯輸出,它的文字就是那個服務的作者最後印了什麼,而廠商既會改它也會把改動往回移植。請用名稱而不是位置來讀欄位,並把沒見過的格式當成差異而不是失敗。

可以用瀏覽器而不是終端機來跑嗎?

很多指令可以——本站的 Web ADB 工具從 Chromium 系桌面瀏覽器透過 WebUSB 和手機對話,不必安裝 SDK,也不會上傳任何東西。每一頁在有對應工具時都會連過去。有兩個限制值得知道:同一時間只有一個程式能持有 ADB 介面,所以桌面的 adb server 要先停掉;而 adb forward 與 adb reverse 在瀏覽器裡完全無法運作。

比較想按而不是打字?Web ADB Toolkit 會從瀏覽器透過 USB 執行這類指令。或者瀏覽全部指令。