Подтвердить что ты не робот

Как сделать скриншот другого приложения программно без разрешения root, например, Скриншот UX Trial?

Как сделать скриншот другого приложения программно без разрешения root, например, Скриншот UX Trial?

  • Я знаю, что могу захватить растровое изображение корневого представления в своем приложении. Но я не могу получить корневой вид другого приложения, когда мое приложение работает в фоновом режиме

    bitmap = Bitmap.createBitmap(rootview.getDrawingCache());

  • Имеется разрешение на захват текущего буфера кадров в манифесте: android.permission.READ_FRAME_BUFFER. Но некоторые веб-сайты говорят, что это только для подписного приложения.

    Проверить права на Android-разрешения - уровни защиты

После попытки Скриншота UX Trial я прочитал разрешение:

  • ИНТЕРНЕТ: для подключения к локальному серверу скриншотов для корневого телефона.
  • SYSTEM_ALERT_WINDOW: для самой верхней кнопки камеры.
  • VIBRATE: для вибросигнала.
  • WRITE_EXTERNAL_STORAGE: сохранить скриншот.
  • GET_TASKS: для обнаружения переднего плана. Действие настройки Develoment для метода без привязки и без предварительной загрузки.

Кажется, что SYSTEM_ALERT_WINDOW или GET_TASKS позволяют приложению делать снимок экрана. У меня есть две догадки о том, как это работает:

  • Он может иметь доступ к Activity активности переднего плана, он получает корневой вид Activity, фиксирует его скриншот.
  • Вызов glreadpixels

Если вы попробуете одно из моих предположений, пожалуйста, дайте мне знать результат.

4b9b3361

Ответ 1

Это чрезвычайно сложно. Я несколько лет пытался это сделать. В конечном итоге мне удалось, но любое решение будет включать как коммерческие, так и технические усилия.


Обновить март 2015

Большая часть приведенного ниже материала больше не актуальна. Теперь, после всех этих лет, пакет android.media.projection https://developer.android.com/reference/android/media/projection/package-summary.html который, наконец, позволяет вам то, что вам нужно!


Захват изображения на экране вашего собственного приложения

Для полноты я хочу включить ваш собственный комментарий, чтобы вы могли захватить изображение своего собственного приложения с помощью Bitmap.createBitmap(rootview.getDrawingCache()); и подобных механизмов.

Захват экрана другого приложения, когда вы находитесь в фоновом режиме

Использование разрешения READ_FRAMEBUFFER

Во-первых, вы правы в том, что обычное приложение не может использовать разрешение READ_FRAMEBUFFER, потому что это "подпись" -уровень. Это означает, что вы должны быть подписаны тем же ключом, что и системное ПЗУ Android, чтобы иметь возможность сделать такой снимок экрана.

Я подумал, что это было немного грустно, поэтому еще в 2009 году я сделал заявку на проект с открытым исходным кодом Android, чтобы попросить его открыть 1. Ответ от Dianne Hackborn, архитектора Android:

Um, no. Абсолютно положительно нет.

Итак, тогда все прошло хорошо! Следовательно, это разрешение по-прежнему signature -уровня по сей день.

Если у вас есть это разрешение, вы можете называть captureScreen членом ISurfaceComposer 2. Вам нужно будет написать собственный код для доступа к этой функции, используя Android NDK, а также некоторые недокументированные API. Однако это возможно.

Внутри графической подсистемы Android используется вызов glReadPixels для извлечения пикселей с графического процессора обратно в CPU. (GPU используется для большинства композиций на Android. Фактически, Android 4.0+ поддерживает дополнительные аппаратные компоненты, а Surface Flinger должен делать еще больше работы, чтобы вернуть эти пиксели в CPU.)

Этот вызов работает красиво, за исключением нескольких небольших проблем:

  • Риск использования неподдерживаемого API, который может сломаться в любой момент;
  • Смысл вызова в С++
  • Это приводит к остановке конвейеров графического процессора, что может нарушить работу графических процессоров, но на самом деле не вызывает проблем на самом деле.
  • Он использует большую пропускную способность от GPU до CPU. Это иногда проблематично, поскольку архитектуры памяти предназначены для отправки данных в противоположном направлении. Однако мне кажется, что все современные архитектуры чипсетов Android напрямую обмениваются памятью между GPU и CPU, за исключением одного (может быть, Broadcom? - я не помню), где это может привести к очень медленному механизму.

... и одна большая проблема...

  • Самое главное, что в качестве обычного писателя приложений вы даже не можете вызывать этот API из-за требуемых разрешений на уровне подписки.

Тем не менее, на большинстве Android-устройств вы можете получить 10 кадров в секунду из этого. Тем не менее, этот API фактически поддерживает масштабирование полученного изображения на оборудовании на графическом процессоре, поэтому, если вы умны, вы можете предварительно масштабировать изображение до нужного размера, прежде чем пиксели даже попадут в CPU. Таким образом, это может быть чрезвычайно высокая производительность.

Обратите внимание, что вы, как писатель приложения, не можете вызвать glReadPixels, потому что у вас нет доступа к соответствующему контексту OpenGL. Он принадлежал поверхностному flinger.

Используя /dev/graphics/fb0 и аналогичные

Некоторые из них пытаются попробовать прочитать эти файлы устройств Linux, которые представляют фреймбуфер. Однако есть три проблемы:

  • Вам нужен root.
  • Иногда их даже нет.
  • Часто они не представляют собой реальное изображение на экране. Помните на Android, что графические элементы компонуются на графическом процессоре. Поэтому нет причин, по которым ЦП должен иметь доступ к копии полного композитного изображения на экране, и часто это не так. Этот файл иногда содержит разрывы (в лучшем случае) и изображение мусора (в худшем случае). Интересно, что некоторые из инструментов для корневых телефонов используют этот метод, который, я думаю, является ошибкой. Если у вас есть root, вы по определению имеете все разрешения на Android и поэтому можете вызвать вышеуказанный API captureScreen, чтобы получить правильное изображение.

Использование аппаратных партнеров

Теперь мы попадаем в решения, требующие коммерческого действия.

Разговор с производителями чипсета Android часто представляет собой решение. Поскольку они проектируют аппаратное обеспечение, у них есть доступ к фреймбуферу - и они часто могут предоставлять библиотеки, которые полностью исключают модель разрешений Android, просто обращаясь к своим пользовательским драйверам ядра напрямую.

Если вы нацелены на определенную модель телефона, это часто хороший путь вперед. Конечно, вероятность того, что вам нужно будет сотрудничать с производителем телефонов, а также с производителем кремния.

Иногда это может обеспечить выдающиеся результаты. Например, я слышал, что на некоторых аппаратных средствах можно напрямую подключить аппаратный фреймбуфер телефона к аппаратным видеокодерам аппаратного H.264 телефона и получить предварительно закодированный видеопоток, который находится на экране телефона. Отлично. (К сожалению, я знаю, что это возможно на чипах TI OMAP, которые постепенно выводятся с рынка телефонов 3).

Использование дырок безопасности

Android жестко применяет свою модель разрешений и имеет несколько дыр в безопасности. Однако OEM-производители Android иногда могут быть более неосторожными.

Например, главный OEM, чье имя начинается с S, реализовал способ захвата экрана с помощью нажатия клавиши. Он сохраняет его в общедоступном для чтения файле на SD-карте. Гипотетически вы могли бы найти, что перехватывает эти ключи и посмотреть, как это работает. Возможно, вы могли бы сделать что-то подобное.

И, возможно, есть способ для другого крупного OEM, имя которого также начинается с S.

Нет, я не буду вдаваться в подробности в этом разделе. Чтобы понять, как это сделать, мне нужно иметь обратное программное обеспечение, и это может быть незаконным. Удачи, однако.

Работа с производителями телефонов

Как описано выше, производители телефонов имеют доступ к API, который работает. И производители телефонов имеют требуемые разрешения signature.

Итак, все, что вам нужно сделать, это организовать, чтобы ваше программное обеспечение было подписано изготовителем телефона.

Это, однако, сложно. Подписывая программное обеспечение, производитель телефона гарантирует его качество - поэтому они должны проверить ваш исходный код. Кроме того, из-за природы Android - если они подписывают программное обеспечение, они должны быть теми, кто его распространяет. Вы не можете поставить его на рынок, если он подписан другой подписью.

Однако OEM не должен включать его в ROM - они все равно могут распространять его на рынке Android. Но вы не можете.

Хорошим решением было бы, если бы каждый поставщик подписал небольшую библиотеку, к которой затем мог получить доступ общий SDK. Это приводит меня к...

Работа с партнерами по программному обеспечению, которые уже решили этот

Я знаю много об этом, потому что я работал в RealVNC. Мы работали со всеми основными поставщиками телефонов Android, чтобы получить доступ к этим API уровня сигнатур. Я не могу переоценить многие, многолетние усилия (коммерчески и технически), необходимые для достижения этого. Некоторые из OEM-производителей опубликовали эту работу - например 4.

Я больше не работаю в RealVNC, поэтому мне нечего выиграть от рекламы своего программного обеспечения. Но если вы действительно хотите захватить экран на нескольких устройствах Android, вы можете обратиться к ним за повторным использованием своей службы удаленного управления или Android VNC SDK 5. Это не open-source, поэтому вы должны рассчитывать на оплату, и поверьте мне, что это достаточно справедливо, учитывая эпические усилия, связанные с работой со всеми этими OEM-производителями Android.

В интересах баланса я должен указать, что другие производители также работали с производителями телефонов на этом - например, Soti. Но я считаю, что все они предлагают конкретные решения по управлению устройствами, а не общий SDK для дистанционного управления/события.

За USB

Другая опция - демон adb, который прослушивает отладку подключений через USB, имеет несколько больше привилегий, чем обычное приложение, поэтому он может захватить экран (вы можете увидеть его изображение с помощью инструмента ddms). Если вы можете запускать любую команду с помощью adb, вы также можете получить эти привилегии (в соответствии с ранее привязанной к андроид-скриншоту библиотекой).

Внести вклад в проект с открытым исходным кодом Android

В конце концов эта проблема уменьшила меня до пыли, и я отправился на более зеленые пастбища, которые не предполагали попытки выжать пиксели из телефонов Android.

Прежде чем я покинул RealVNC, мы попытались снова внести эти API в проект с открытым исходным кодом Android. На этот раз мы получили более позитивную реакцию 6, Короче говоря, было высказано предположение о том, что наш подход к обеспечению безопасности был почти прав, но что графическая система была в слишком суматохе, чтобы принять наши исправления. Ну, отличная новость заключается в том, что графическая система больше не находится в смятении - на самом деле теперь она имеет API captureScreen, что означает, что никаких изменений в графической системе не требуется. Поэтому, возможно, можно представить новый механизм безопасности для AOSP вокруг этого API, который, наконец, решает эту проблему.

Удачи!

Ответ 2

Возможно, может помочь android-screenshot-library. Но хорошо на странице "Использование" говорится, что для него требуется родной сервис, начинающийся с adb (из sroid sroid).

PS: Помните, что скриншот UX не работает для каждого некорневого телефона.

Ответ 3

Я не думаю, что Android позволит вам получить доступ к другому буферу фрейма приложения. Это всего лишь часть безопасности Android. Каждое приложение должно поддерживать свои ресурсы.

Если вам действительно нужно получить захват экрана для любого приложения, я бы предложил использовать собственный жест "захвата" экрана. Например, для Nexus 7 просто "... удерживайте кнопку питания и кнопку уменьшения громкости одновременно в течение примерно 2 секунд."

Поиск Google обычно найдет трюк с вашим устройством.