I'm trying to get a screenshot of a window, basically a bitmap. I need to also get the screenshot from accelerated hardware devices.
I have implemented the PixelCopy API as the following:
PixelCopyUtils
@RequiresApi(Build.VERSION_CODES.O)
object PixelCopyUtils {
fun getViewBitmap(window: Window, event: (PixelCopyEvents) -> Unit) {
val bitmap = Bitmap.createBitmap(window.decorView.rootView.width, window.decorView.rootView.height, Bitmap.Config.ARGB_8888)
val handlerThread = HandlerThread(PixelCopyUtils::class.java.simpleName)
handlerThread.start()
PixelCopy.request(window, bitmap, { copyResult ->
if (copyResult == PixelCopy.SUCCESS) {
event(PixelCopyEvents.OnCopySuccess(bitmap))
} else {
event(PixelCopyEvents.OnCopyError)
}
handlerThread.quitSafely()
}, Handler(handlerThread.looper))
}
sealed interface PixelCopyEvents {
object OnCopyError: PixelCopyEvents
data class OnCopySuccess(val bitmap: Bitmap): PixelCopyEvents
}
}
extension function that is being called from the window I want to get the bitmap from
@RequiresApi(Build.VERSION_CODES.O)
fun Window.onViewDraw(isReady: (Bitmap?) -> Unit) {
this.decorView.rootView.post {
PixelCopyUtils.getViewBitmap(this) { event ->
when(event) {
PixelCopyUtils.PixelCopyEvents.OnCopyError -> {
logging(TAG, "Error while getting the screenshot through PixelCopy API.")
isReady(null)
}
is PixelCopyUtils.PixelCopyEvents.OnCopySuccess -> {
isReady(event.bitmap)
}
}
}
}
}
It worked many times but I see sometimes I get the following crash:
Exception java.lang.IllegalArgumentException: Window doesn't have a backing surface!
at android.view.PixelCopy.request (PixelCopy.java:278)
at android.view.PixelCopy.request (PixelCopy.java:223)
at android.os.Handler.handleCallback (Handler.java:883)
at android.os.Handler.dispatchMessage (Handler.java:100)
at android.os.Looper.loop (Looper.java:237)
at android.app.ActivityThread.main (ActivityThread.java:8167)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1100)
I don't know why this behaviour is happening if the PixelCopy is triggered after the view is drawn. Thanks in advance.