我有下面的代码,它在Android 12及以下版本上运行得非常好,但出于一个奇怪的原因,Android 13在95%的情况下都会截图为“黑色”。
fun setVirtualDisplay() {
mImageReader = ImageReader.newInstance(
deviceScreenUtils.getWidth(),
deviceScreenUtils.getHeight(),
PixelFormat.RGBA_8888,
2
)
mImageReader?.let {
val flags =
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY or DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
try {
mVirtualDisplay = mMediaProjection?.createVirtualDisplay(
"screen-mirror", deviceScreenUtils.getWidth(), deviceScreenUtils.getHeight(),
deviceScreenUtils.getDensity(), flags, it.surface, null, null
)
} catch (e: Throwable) {
Log.i(TAG, "Media Projection not longer available...")
mMediaProjectionIntent = null
mImageReader = null
}
}
}
fun takeScreenshot() {
Log.i(TAG, "Taking screenshot...")
val handler = Handler(Looper.getMainLooper())
mImageReader?.setOnImageAvailableListener({ imageReader ->
val image = imageReader.acquireLatestImage()
Log.i(TAG, "Acquiring image...")
if (image != null) {
val planes = image.planes
val buffer = planes[0].buffer
val pixelStride = planes[0].pixelStride
val rowStride = planes[0].rowStride
val rowPadding: Int = rowStride - pixelStride * deviceScreenUtils.getWidthPixels()
val bitmap = Bitmap.createBitmap(
deviceScreenUtils.getWidth() + (rowPadding.toFloat() / pixelStride.toFloat()).toInt(),
deviceScreenUtils.getHeight(),
Bitmap.Config.ARGB_8888
)
bitmap.copyPixelsFromBuffer(buffer)
image.close()
fileUtil.saveImage(bitmap)?.let {
lastScreenshot.onNext(it)
}
}
imageReader.setOnImageAvailableListener(null, handler)
releaseBuffer()
}, handler)
}
这个特定的功能有什么改变吗?或者我的代码有什么错误,它在以前的版本中神奇地工作着?
1条答案
按热度按时间kmpatx3s1#
在我的测试和观察中,在Android 13上使用ImageReader和媒体投影时存在两个问题
首先,
setOnImageAvailableListener
的回调结果有时会返回空像素的缓冲区。isEmptyBitmap()只是位图扩展:
第二个问题是,
OnImageAvailableListener
有时甚至不回调!在本例中,我设置了一个超时来等待结果,当超时时,从同一个MediaProjection示例重新创建VirtualDisplay对象,它就可以正常工作了。我使用的是Kotlin协程,因此代码片段可能看起来像:
awaitImageAvailable
: