Скриншот через screencap:
На устройстве живет встроенная утилита screencap. Флаг -p заставляет ее отдавать PNG. Канонический способ получить картинку сразу на компьютер:
Код: Выделить всё
adb exec-out screencap -p > screen.pngКод: Выделить всё
$ file screen.png
screen.png: PNG image data, 1080 x 2400, 8-bit/color RGBA, non-interlacedВторой вариант, через файл на устройстве:
Код: Выделить всё
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png ./screen.png
adb shell rm /sdcard/screen.pngКод: Выделить всё
/sdcard/screen.png: 1 file pulled, 0 skipped. 38.5 MB/s (1474560 bytes in 0.037s)Если дисплеев несколько (складные аппараты, десктопный режим, Android Auto), сначала узнайте id:
Код: Выделить всё
$ adb shell dumpsys SurfaceFlinger --display-id
Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="EMU_display_0"Код: Выделить всё
adb exec-out screencap -p -d 4619827259835644672 > cover.pngЗапись видео через screenrecord:
Утилита /system/bin/screenrecord существует со времен Android 4.4 и пишет MP4 с кодеком H.264. Звук она не записывает вообще, это ограничение самой утилиты, и root тут не помогает. Запись идет в файл на устройстве:
Код: Выделить всё
adb shell screenrecord /sdcard/demo.mp4Код: Выделить всё
adb shell screenrecord --time-limit 30 /sdcard/demo.mp4Код: Выделить всё
$ adb shell screenrecord --time-limit 600 /sdcard/demo.mp4
Time limit 600s outside acceptable range [1,180]Код: Выделить всё
adb shell screenrecord --size 720x1600 /sdcard/demo.mp4Код: Выделить всё
ERROR: unable to configure video/avc codec at 1083x2412 (err=-38)Флаг --bit-rate принимает битрейт в битах в секунду, можно с суффиксом M. На свежих Android по умолчанию 20 Мбит/с (на старых было 4). Для ролика в чат разумно ужать:
Код: Выделить всё
adb shell screenrecord --bit-rate 4M --time-limit 60 /sdcard/bug.mp4Код: Выделить всё
$ adb shell screenrecord --verbose --time-limit 10 /sdcard/demo.mp4
Main display is 1080x2400 @60.00fps (orientation=0)
Configuring recorder for 1080x2400 video/avc at 20000000bps
Content area is 1080x2400 at offset x=0 y=0
Encoder stopping; recorded 594 frames in 10 seconds
Stopping encoder and muxerПрерывание и корректная остановка:
В интерактивной сессии запись останавливается по Ctrl+C. screenrecord ловит SIGINT, дописывает индекс MP4 (атом moov) и закрывает файл. Убивать процесс через kill -9 нельзя: контейнер останется без индекса, и плеер такой файл не откроет (ffmpeg иногда вытаскивает поток, но рассчитывать на это не надо).
Фоновую запись останавливайте тем же сигналом:
Код: Выделить всё
adb shell pkill -2 screenrecordИзвлечение записи:
Код: Выделить всё
$ adb pull /sdcard/demo.mp4 .
/sdcard/demo.mp4: 1 file pulled, 0 skipped. 41.2 MB/s (24816512 bytes in 0.574s)
$ adb shell rm /sdcard/demo.mp4Код: Выделить всё
adb exec-out screenrecord --output-format=h264 - | ffplay -framerate 60 -probesize 32 -sync video -Обработка скриншотов в скриптах:
Серия снимков с таймстампами в имени:
Код: Выделить всё
#!/usr/bin/env bash
set -euo pipefail
SERIAL="RF8X20KQ1ZT"
OUT=./shots
mkdir -p "$OUT"
for i in $(seq 1 10); do
adb -s "$SERIAL" exec-out screencap -p > "$OUT/shot_$(date +%Y%m%d_%H%M%S).png"
sleep 2
doneСкриншоты отлично стыкуются с ImageMagick. Сравнить два состояния экрана и получить число отличающихся пикселей:
Код: Выделить всё
$ magick compare -metric AE before.png after.png diff.png
14302Код: Выделить всё
$ magick screen.png -format "%[pixel:p{540,1200}]" info:
srgb(76,175,80)Отдельная боль на Windows. В классическом Windows PowerShell 5.1 оператор перенаправления перекодирует поток, и PNG приходит битым даже через exec-out. Лечится запуском через cmd:
Код: Выделить всё
cmd /c "adb exec-out screencap -p > screen.png"Запись видео вокруг прогона тестов, целиком:
Код: Выделить всё
#!/usr/bin/env bash
set -euo pipefail
adb shell "screenrecord --bit-rate 8M --time-limit 180 /sdcard/test_run.mp4" &
REC_PID=$!
./run_ui_tests.sh || true
adb shell pkill -2 screenrecord || true
wait "$REC_PID" 2>/dev/null || true
sleep 2
adb pull /sdcard/test_run.mp4 ./artifacts/
adb shell rm /sdcard/test_run.mp4Черный прямоугольник вместо содержимого. Окно выставило FLAG_SECURE, и система не отдает его пиксели ни скриншоту, ни записи. Банковские приложения (Сбер, Kaspi), Госуслуги, DRM-видео, поля с паролями. Штатного обхода нет, и это правильно. В своем приложении флаг можно убрать в debug-сборке.
Черный скриншот при погасшем экране. screencap снимает то, что выводится на дисплей, спящее устройство дает черный кадр. Разбудите его через input keyevent KEYCODE_WAKEUP (глава 11).
PNG не открывается на Windows. Смотрите выше про PowerShell 5.1, либо у вас древние platform-tools и снимок делался через adb shell с перенаправлением. Обновитесь до актуальной ветки 36.x и используйте exec-out.
Time limit outside acceptable range. Попытка задать --time-limit больше 180. Длинные записи делайте сегментами в цикле или через scrcpy --record file.mp4.
unable to configure video/avc codec. Кодировщик не принял запрошенный --size. Берите стандартные размеры или родное разрешение.
Файл не воспроизводится. Процесс убили через kill -9 или выдернули кабель до финализации. Только Ctrl+C или pkill -2, потом пауза, потом pull.
Поворот экрана во время записи. screenrecord не меняет ориентацию на лету: видео остается в той ориентации, в которой стартовало, контент после поворота вписывается с полями или обрезается. Не вертите устройство в кадре, либо режьте ролик на дубли.
На эмуляторе screenrecord работает в свежих системных образах, а у самого эмулятора есть и собственный механизм записи, про него поговорим в главе 21. В следующей главе займемся root-доступом и тем, что он открывает поверх уже знакомых команд.