直接上代码:
入口方法: startTakeScreenShot()
出口方法:返回的Bitmap对象在onActivityResult()? 有todo的注释
注意:该截屏方式 在 build.gradle属性 stargetSdk >=30 的情况下会报错。我这边是28。
val EVENT_SCREENSHOT = 22 //截图事件
private var mediaProjectionManager: MediaProjectionManager? = null
private var mediaProjection: MediaProjection? = null
private var image: Image? = null
// 开始截屏方法
fun startTakeScreenShot() {
mediaProjectionManager =
application.getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
startActivityForResult(
mediaProjectionManager!!.createScreenCaptureIntent(),
EVENT_SCREENSHOT
)
}
@SuppressLint("WrongConstant")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_PIC) {
if (data != null) {
val pathList: List<String>? =
data.getStringArrayListExtra(Repair_ImgSelActivity.INTENT_RESULT)
doPicDataS(pathList)
}
}
if (requestCode == EVENT_SCREENSHOT) {
super.onActivityResult(requestCode, resultCode, data)
Log.e("whh0914", "captureScreen...")
val displayMetrics = DisplayMetrics()
val windowManager = this.getSystemService(WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay.getMetrics(displayMetrics)
val width = displayMetrics.widthPixels
val height = displayMetrics.heightPixels
val mImageReader: ImageReader =
ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2)
mediaProjection = mediaProjectionManager?.getMediaProjection(resultCode, data!!)
val virtualDisplay = mediaProjection?.createVirtualDisplay(
"screen-mirror",
width,
height,
displayMetrics.densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mImageReader.surface,
null,
null
)
Handler().postDelayed(Runnable {
try {
image = mImageReader.acquireLatestImage()
if (image != null) {
val planes: Array<Image.Plane> = image!!.planes
val buffer: ByteBuffer = planes[0].buffer
val width: Int = image!!.width
val height: Int = image!!.height
val pixelStride: Int = planes[0].pixelStride
val rowStride: Int = planes[0].rowStride
val rowPadding = rowStride - pixelStride * width
var bitmap = Bitmap.createBitmap(
width + rowPadding / pixelStride,
height,
Bitmap.Config.ARGB_8888
)
bitmap!!.copyPixelsFromBuffer(buffer)
bitmap =
Bitmap.createScaledBitmap(bitmap, bitmap.width, bitmap.height, false)
val pipelineFragment = viewPagerAdapter.fragmentList[1] as PipelineFragment
pipelineFragment.mWebView.visibility = View.GONE
if (bitmap != null) {
// 这里获取到截到的Bitmap对象
// 下面是将bitmap保存到SD卡中的方法:如有需要请参考博客:https://blog.csdn.net/qq_39731011/article/details/123640342 如不需要请删除
ImageSaveUtil.saveAlbum(this,bitmap,
Bitmap.CompressFormat.JPEG, 80, true)
}
bitmap.recycle()
}
} catch (e: java.lang.Exception) {
Log.e("截图", "出现异常:$e")
} finally {
if (image != null) {
image!!.close()
}
if (mImageReader != null) {
mImageReader.close()
}
virtualDisplay?.release()
//该代码为了避免出现BufferQueueProducer: [ImageReader] dequeueBuffer: BufferQueue has been abandoned
mImageReader.setOnImageAvailableListener(null, null)
mediaProjection?.stop()
}
}, 300)//这里的延迟是为了 不截取到 系统提示是否允许录屏的弹框,可自行调整,经深海测试一般100-500为最佳
}
}
|