android 使用MediaProjection API在屏幕录制期间捕获屏幕截图

esbemjvw  于 2024-01-04  发布在  Android
关注(0)|答案(1)|浏览(168)

我有一个服务类,我正在捕获屏幕记录。我想在这个类中截图,但我没有找到任何合适的方法来这样做。有人能建议一种方法来在服务类中截图吗?
下面是在屏幕录制期间初始化的mediaProjection和virtualDisplay对象

  1. mMediaProjection = (Objects.requireNonNull(
  2. getSystemService(
  3. MEDIA_PROJECTION_SERVICE
  4. )
  5. ) as MediaProjectionManager).getMediaProjection(
  6. mResultCode,
  7. mResultData!!
  8. )
  9. mVirtualDisplay = mMediaProjection!!.createVirtualDisplay(
  10. TAG,
  11. mScreenWidth,
  12. mScreenHeight,
  13. mScreenDensity,
  14. DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
  15. mMediaRecorder!!.surface,
  16. null,
  17. null
  18. )

字符串
这是我的截图代码

  1. var imageReader: ImageReader? = null // Initialize as needed
  2. // Call this function to capture a screenshot
  3. private fun captureScreenshot() {
  4. if (imageReader == null) {
  5. // Set up ImageReader to capture the screen content
  6. val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
  7. val metrics = DisplayMetrics()
  8. windowManager.defaultDisplay.getMetrics(metrics)
  9. val screenDensity = metrics.densityDpi
  10. val screenWidth = metrics.widthPixels
  11. val screenHeight = metrics.heightPixels
  12. imageReader = ImageReader.newInstance(screenWidth, screenHeight, ImageFormat.RGB_565, 1)
  13. // Set the OnImageAvailableListener to handle new images
  14. imageReader!!.setOnImageAvailableListener({ reader ->
  15. // Process the captured image data
  16. val image = reader.acquireLatestImage()
  17. if (image != null) {
  18. try {
  19. // Your image processing logic here
  20. processImage(image)
  21. } finally {
  22. // Always close the image to avoid resource leaks
  23. image.close()
  24. }
  25. }
  26. }, Handler())
  27. }
  28. }
  29. private fun processImage(image: Image) {
  30. val planes = image.planes
  31. val buffer = planes[0].buffer
  32. val pixelStride = planes[0].pixelStride
  33. val rowStride = planes[0].rowStride
  34. val rowPadding = rowStride - pixelStride * image.width
  35. // Create a Bitmap to hold the screenshot
  36. val bitmap = Bitmap.createBitmap(
  37. image.width + rowPadding / pixelStride,
  38. image.height,
  39. Bitmap.Config.ARGB_8888
  40. )
  41. bitmap.copyPixelsFromBuffer(buffer)
  42. // Save the bitmap to a file (You may want to handle this more appropriately)
  43. saveBitmapToFile(bitmap)
  44. }
  45. private fun getParentFolder(): String {
  46. return "${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)}/${
  47. getString(R.string.app_name)
  48. }"
  49. }
  50. private fun saveBitmapToFile(bitmap: Bitmap) {
  51. Log.d("de_save", "saveBitmapToFile: ")
  52. try {
  53. // Save the bitmap to a file (You may want to handle this more appropriately)
  54. val savePath = getFolder()
  55. Log.d("de_save", "saveBitmapToFile: savepath: $savePath")
  56. val file = File(savePath, "ScreenShot_${System.currentTimeMillis()}")
  57. val fileOutputStream = FileOutputStream(file)
  58. bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
  59. fileOutputStream.close()
  60. ToastUtils.showToast("Screenshot Taken")
  61. } catch (e: IOException) {
  62. e.printStackTrace()
  63. }
  64. }
  65. private fun getFolder(): String {
  66. val location = getParentFolder() + File.separator + "ScreenShot"
  67. val file = File(location)
  68. if (!file.exists()) {
  69. file.mkdirs()
  70. }
  71. return location
  72. }


使用这段代码,setOnImageController.exe永远不会被调用。

wdebmtf2

wdebmtf21#

You should use ImageReader's surface in Windows VirtualDisplay. but in Android14中会中断记录。

相关问题