Где живут настройки:
Все параметры, которые вы видите в приложении "Настройки", и сотни тех, которых там нет, Android хранит в SettingsProvider. Это системный поставщик контента внутри процесса system_server, со времён Android 6 данные лежат в XML-файлах в /data/system/users/<id>/ и /data/system/. Утилита settings - консольный клиент к этому провайдеру. Главное: shell-пользователь (uid 2000), от имени которого работает adb shell, владеет разрешениями WRITE_SETTINGS и WRITE_SECURE_SETTINGS. Поэтому из ADB можно читать и писать почти всё без root, тогда как обычным приложениям запись в secure и global закрыта в принципе.
Настройки разбиты на три пространства имён:
system. Пользовательские параметры текущего профиля: яркость (screen_brightness), таймаут экрана (screen_off_timeout), масштаб шрифта (font_scale), автоповорот, рингтоны, виброотклик.
secure. Чувствительные параметры профиля: android_id, выбранная клавиатура (default_input_method), службы accessibility, принудительный DPI. Приложения могут их читать, но не писать.
global. Общие для всего устройства и всех пользователей: airplane_mode_on, adb_enabled, масштабы анимаций, development_settings_enabled, stay_on_while_plugged_in.
Пять глаголов:
Код: Выделить всё
adb shell settings list <namespace>
adb shell settings get <namespace> <key>
adb shell settings put <namespace> <key> <value>
adb shell settings delete <namespace> <key>
adb shell settings reset <namespace> <режим|пакет>
Код: Выделить всё
$ adb shell settings list global
adb_enabled=1
airplane_mode_on=0
airplane_mode_radios=cell,bluetooth,wifi,nfc,wimax
animator_duration_scale=1.0
bluetooth_on=1
boot_count=42
...
Код: Выделить всё
$ adb shell settings list system | grep screen
screen_brightness=98
screen_brightness_mode=1
screen_off_timeout=30000
Код: Выделить всё
$ adb shell settings get secure android_id
3f8c1de29a4b5c6d
$ adb shell settings put system screen_off_timeout 60000
$ adb shell settings delete global my_test_key
Deleted 1 rows
reset работает только для secure и global и откатывает изменения пакетами: режимы untrusted_defaults, untrusted_clear, trusted_defaults либо имя конкретного пакета. На практике я предпочитаю точечный delete, у reset слишком широкий радиус поражения.
На устройствах с несколькими пользователями (рабочий профиль, "второе пространство" на HyperOS, профили на Android TV) добавляйте флаг --user, иначе пишете в профиль 0:
Код: Выделить всё
$ adb shell pm list users
Users:
UserInfo{0:Owner:c13} running
UserInfo{10:Work:1030} running
$ adb shell settings get --user 10 system screen_brightness
64
Пример 1, режим полёта:
Классическая ловушка. Запись значения меняет только флаг, радиомодули остаются включёнными:
Код: Выделить всё
adb shell settings put global airplane_mode_on 1
Код: Выделить всё
$ adb shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true
java.lang.SecurityException: Permission Denial: not allowed to send broadcast
android.intent.action.AIRPLANE_MODE from pid=12903, uid=2000
Код: Выделить всё
adb shell cmd connectivity airplane-mode enable
adb shell cmd connectivity airplane-mode disable
adb shell cmd connectivity airplane-mode
enabled
Пример 2, яркость:
Сначала выключите автояркость, иначе ваше значение тут же перезапишется:
Код: Выделить всё
adb shell settings put system screen_brightness_mode 0
adb shell settings put system screen_brightness 128
Пример 3, таймаут экрана:
Значение в миллисекундах:
Код: Выделить всё
adb shell settings put system screen_off_timeout 600000
Код: Выделить всё
adb shell svc power stayon usb
Пример 4, DPI:
Принудительная плотность хранится в secure-ключе display_density_forced, и именно его пишет знакомая по главе 13 команда wm density:
Код: Выделить всё
$ adb shell wm density 356
$ adb shell settings get secure display_density_forced
356
Бонус для автоматизации (пригодится в главе 24): отключение анимаций и наглядные касания:
Код: Выделить всё
adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0
adb shell settings put system show_touches 1
adb shell settings put system pointer_location 1
Утилита settings - надстройка над SettingsProvider, а к нему можно обращаться и напрямую командой content (подробно она ждёт вас в главе 17). URI стандартные: content://settings/system, content://settings/secure, content://settings/global.
Код: Выделить всё
$ adb shell content query --uri content://settings/global --where "name='adb_enabled'"
Row: 0 _id=25, name=adb_enabled, value=1
Код: Выделить всё
adb shell content insert --uri content://settings/system --bind name:s:screen_brightness --bind value:i:200
Код: Выделить всё
adb shell content delete --uri content://settings/system --where "name='my_test_key'"
Код: Выделить всё
adb shell pm grant com.example.app android.permission.WRITE_SECURE_SETTINGS
Поставили global adb_enabled 0 и устройство пропало из adb devices. Лечится только руками на устройстве через настройки разработчика, на удалённой ферме это поездка в серверную.
Советы из статей 2018-2020 годов про settings put global policy_control immersive.full=* больше не работают, ключ policy_control удалён в Android 11.
Меняете настройку, а на экране ничего: проверьте, не пишете ли вы не тому пользователю (флаг --user current) и не перебивает ли вас автояркость или родительский контроль.
Значение с пробелами экранируйте с учётом двойного прохода через shell:
Код: Выделить всё
adb shell "settings put global device_name 'Test Pixel 8'"