Использование mediaprojectionmanager для получения снимков экрана, когда другое приложение находится на переднем плане ⇐ Android
Использование mediaprojectionmanager для получения снимков экрана, когда другое приложение находится на переднем плане
Работаю над личным проектом по использованию API менеджера медиапроекции для создания приложения Android, которое позволяет мне делать снимок экрана всякий раз, когда я говорю «скриншот», а затем конвертировать его в растровое изображение и отправлять его в другую функцию для обработки. Затем он распознает, что изображено на изображении, и произносит это вслух. Однако документация не очень хорошая, а примеры, просмотренные на форумах, привели меня к этому коду, который до сих пор не работает. Во-первых, он выдает несколько ошибок в студии Android. Но даже если я попытаюсь решить их, в лучшем случае я просто получу черное растровое изображение или приложение выйдет из строя. У меня есть служба переднего плана, работающая в фоновом режиме, которая вызывает службу захвата экрана. Вот как сейчас выглядит служба захвата экрана. Я работал над этим неделю, и это настоящая головная боль.
`
импортировать android.app.Service
импортировать android.content.Intent
импортировать android.os.IBinder
импортировать android.os.Handler
импортировать android.os.Looper
импортировать android.media.projection.MediaProjection
импортировать android.media.projection.MediaProjectionManager
импортировать android.util.DisplayMetrics
импортировать android.view.WindowManager
импортировать android.graphics.Bitmap
импортировать android.media.Image
импортировать android.media.ImageReader
импортировать java.io.FileOutputStream
импортировать java.io.IOException
импортировать java.nio.ByteBuffer
класс ScreenshotService : Service() {
private lateinit var mediaProjectionManager: MediaProjectionManager частный lateinit var mediaProjection: MediaProjection частный lateinit var imageReader: ImageReader частный обработчик lateinit var: Handler переопределить удовольствие onBind(намерение: Намерение?): IBinder? { вернуть ноль } переопределить удовольствие onCreate() { супер.onCreate() // Инициализируем MediaProjectionManager и создаем обработчик в главном цикле mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) как MediaProjectionManager обработчик = Обработчик(Looper.getMainLooper()) } переопределить fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { // Запускаем медиапроекцию при запуске службы стартМедиаПроекция() вернуть START_STICKY } частное развлечение startMediaProjection() { // Получение resultCode и дополнительных данных Intent, переданных в службу val resultCode = намерение?.getIntExtra("resultCode", -1) val data = намерение?.getParcelableExtra("данные") if (resultCode != -1 && данные != null) { // Получаем экземпляр MediaProjection с помощью MediaProjectionManager mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data) val windowManager = getSystemService(Context.WINDOW_SERVICE) как WindowManager val метрики = DisplayMetrics() windowManager.defaultDisplay.getMetrics(метрики) // Настраиваем ImageReader для захвата снимков экрана imageReader = ImageReader.newInstance(metrics.widthPixels, metrics.heightPixels, PixelFormat.RGBA_8888, 2) mediaProjection.createVirtualDisplay( "Скриншот", метрика.ширинаПиксели, метрики.высотаПиксели, метрика.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, изображениеReader.surface, нулевой, нулевой ) // Начинаем делать снимки экрана в фоновом режиме захватаскриншотов() } } личное развлечение captureScreenshots() { imageReader.setOnImageAvailableListener({читатель -> val image = reader.acquireLatestImage() если (изображение != ноль) { // Здесь обрабатываем скриншот val растровое изображение = imageToBitmap(изображение) saveBitmapToFile (растровое изображение) изображение.закрыть() } }, обработчик) } личное развлечение imageToBitmap(изображение: Изображение): Bitmap { val planes = image.planes буфер val: ByteBuffer = planes[0].buffer val PixelStride: Int = planes[0].pixelStride val rowStride: Int = planes[0].rowStride val rowPadding = rowStride - PixelStride * image.width val растровое изображение = Bitmap.createBitmap( image.width + rowPadding/pixelStride, изображение.высота, Bitmap.Config.ARGB_8888 ) // Копируем данные изображения в растровое изображение bitmap.copyPixelsFromBuffer(буфер) вернуть растровое изображение } личное развлечение saveBitmapToFile (растровое изображение: растровое изображение) { // Сохраняем растровое изображение в файл или выполняем любое желаемое действие пытаться { val fos = FileOutputStream("/path/to/screenshot.png") bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos) фос.закрыть() } catch (e: IOException) { е.printStackTrace() } }
` Любая помощь приветствуется, я знаю, что проще использовать программу чтения с экрана и т. д., но я пытаюсь это не делать. Люблю испытания, но все еще новичок в Android
Работаю над личным проектом по использованию API менеджера медиапроекции для создания приложения Android, которое позволяет мне делать снимок экрана всякий раз, когда я говорю «скриншот», а затем конвертировать его в растровое изображение и отправлять его в другую функцию для обработки. Затем он распознает, что изображено на изображении, и произносит это вслух. Однако документация не очень хорошая, а примеры, просмотренные на форумах, привели меня к этому коду, который до сих пор не работает. Во-первых, он выдает несколько ошибок в студии Android. Но даже если я попытаюсь решить их, в лучшем случае я просто получу черное растровое изображение или приложение выйдет из строя. У меня есть служба переднего плана, работающая в фоновом режиме, которая вызывает службу захвата экрана. Вот как сейчас выглядит служба захвата экрана. Я работал над этим неделю, и это настоящая головная боль.
`
импортировать android.app.Service
импортировать android.content.Intent
импортировать android.os.IBinder
импортировать android.os.Handler
импортировать android.os.Looper
импортировать android.media.projection.MediaProjection
импортировать android.media.projection.MediaProjectionManager
импортировать android.util.DisplayMetrics
импортировать android.view.WindowManager
импортировать android.graphics.Bitmap
импортировать android.media.Image
импортировать android.media.ImageReader
импортировать java.io.FileOutputStream
импортировать java.io.IOException
импортировать java.nio.ByteBuffer
класс ScreenshotService : Service() {
private lateinit var mediaProjectionManager: MediaProjectionManager частный lateinit var mediaProjection: MediaProjection частный lateinit var imageReader: ImageReader частный обработчик lateinit var: Handler переопределить удовольствие onBind(намерение: Намерение?): IBinder? { вернуть ноль } переопределить удовольствие onCreate() { супер.onCreate() // Инициализируем MediaProjectionManager и создаем обработчик в главном цикле mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) как MediaProjectionManager обработчик = Обработчик(Looper.getMainLooper()) } переопределить fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { // Запускаем медиапроекцию при запуске службы стартМедиаПроекция() вернуть START_STICKY } частное развлечение startMediaProjection() { // Получение resultCode и дополнительных данных Intent, переданных в службу val resultCode = намерение?.getIntExtra("resultCode", -1) val data = намерение?.getParcelableExtra("данные") if (resultCode != -1 && данные != null) { // Получаем экземпляр MediaProjection с помощью MediaProjectionManager mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data) val windowManager = getSystemService(Context.WINDOW_SERVICE) как WindowManager val метрики = DisplayMetrics() windowManager.defaultDisplay.getMetrics(метрики) // Настраиваем ImageReader для захвата снимков экрана imageReader = ImageReader.newInstance(metrics.widthPixels, metrics.heightPixels, PixelFormat.RGBA_8888, 2) mediaProjection.createVirtualDisplay( "Скриншот", метрика.ширинаПиксели, метрики.высотаПиксели, метрика.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, изображениеReader.surface, нулевой, нулевой ) // Начинаем делать снимки экрана в фоновом режиме захватаскриншотов() } } личное развлечение captureScreenshots() { imageReader.setOnImageAvailableListener({читатель -> val image = reader.acquireLatestImage() если (изображение != ноль) { // Здесь обрабатываем скриншот val растровое изображение = imageToBitmap(изображение) saveBitmapToFile (растровое изображение) изображение.закрыть() } }, обработчик) } личное развлечение imageToBitmap(изображение: Изображение): Bitmap { val planes = image.planes буфер val: ByteBuffer = planes[0].buffer val PixelStride: Int = planes[0].pixelStride val rowStride: Int = planes[0].rowStride val rowPadding = rowStride - PixelStride * image.width val растровое изображение = Bitmap.createBitmap( image.width + rowPadding/pixelStride, изображение.высота, Bitmap.Config.ARGB_8888 ) // Копируем данные изображения в растровое изображение bitmap.copyPixelsFromBuffer(буфер) вернуть растровое изображение } личное развлечение saveBitmapToFile (растровое изображение: растровое изображение) { // Сохраняем растровое изображение в файл или выполняем любое желаемое действие пытаться { val fos = FileOutputStream("/path/to/screenshot.png") bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos) фос.закрыть() } catch (e: IOException) { е.printStackTrace() } }
` Любая помощь приветствуется, я знаю, что проще использовать программу чтения с экрана и т. д., но я пытаюсь это не делать. Люблю испытания, но все еще новичок в Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение