#### # 참고
- https://developer.android.com/reference/android/media/projection/MediaProjection
- https://thdev.tech/androiddev/2016/04/09/Android-MediaProjection-Exmple/
- https://github.com/taehwandev/MediaProjectionExample
- https://www.google.com/search?q=mediaprojection&rlz=1C5CHFA_enKR955KR955&oq=mediaProj&aqs=chrome.3.69i57j35i39i650j35i39j0i512l2j69i60l3.9320j0j9&sourceid=chrome&ie=UTF-8
- https://bictoselfdev.blogspot.com/2023/01/mediaProjectionCaptureEx.html
- https://github.com/bictoselfdev/MediaProjectionEx
- https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=wns9223&logNo=220849094218
- https://github.com/mtsahakis/MediaProjectionDemo
- https://daisyleh.blogspot.com/2019/03/mediaprojection.html
#### # 개념
1. 권한 받기
2. 가상화면 생셩 : Surface가 연결된 Virtual Display생성
- Virtual Display : MediaProjection이 올려주는 데이터를 받음
- Surface : Virtual Display와 연결되어 받은 데이터를 활용 할 수 있음
- Capture
- Recording
#### # MediaProjection 권한을 위한 Foreground Service
```
java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
```
#### # AndroidManifest.xml
```xml
```
```xml
```
```ts
private var prevIntentData: Intent? = null
private var prevResultCode = 0
fun screenCapture(activity: Activity, action: Consumer?) {
captureCompletedAction = action
if (prevIntentData != null) {
// If you have received permission even once, proceed without requesting permission
getMediaProjectionCapture(activity, prevResultCode, prevIntentData)
} else {
// permission request
projectionManager = activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
activity.startActivityForResult(projectionManager?.createScreenCaptureIntent(), mediaScreenCapture)
}
}
fun getMediaProjectionCapture(activity: Activity, resultCode: Int, intentData: Intent?) {
projectionCapture = projectionManager?.getMediaProjection(resultCode, intentData!!)
if (projectionCapture != null) {
prevIntentData = intentData
prevResultCode = resultCode
// Create virtualDisplay
createVirtualDisplayCapture(activity)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
MediaProjectionController.mediaScreenCapture -> {
MediaProjectionController.getMediaProjectionCapture(this, resultCode, data)
}
MediaProjectionController.mediaScreenRecord -> {
MediaProjectionController.getMediaProjectionRecord(this, resultCode, data)
}
}
}
private fun createVirtualDisplayCapture(activity: Activity) {
val metrics = activity.resources?.displayMetrics!!
val density = metrics.densityDpi
val flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY or DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
width = metrics.widthPixels
height = metrics.heightPixels
// called when there is a new image : OnImageAvailableListener
imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2)
imageReader?.setOnImageAvailableListener(ImageAvailableListener(), null)
// ImageReader Surface rendering
virtualDisplayCapture = projectionCapture?.createVirtualDisplay(
"screenCapture", width, height, density, flags,
imageReader?.surface, null, null
)
}
private class ImageAvailableListener : OnImageAvailableListener {
override fun onImageAvailable(reader: ImageReader) {
var image: Image? = null
try {
image = reader.acquireLatestImage()
if (image != null) {
val planes = image.planes
val buffer = planes[0].buffer
val pixelStride = planes[0].pixelStride
val rowStride = planes[0].rowStride
val rowPadding = rowStride - pixelStride * width
// Create bitmap
var bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888)
bitmap.copyPixelsFromBuffer(buffer)
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height)
projectionCapture?.stop()
captureCompletedAction?.accept(bitmap)
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
image?.close()
}
}
}
```
===============================================================================
#### # 단계
1. MediaProjectionManager는 getSystemService를 통해 service를 생성
```java
MediaProjectionManager mpm = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
startActivityForResult(mpm.createScreenCaptureIntent(), REQUEST_CODE);
```
1. 권한 획득
- onActivityResult
- MediaProjection 생성 사용
```java
private MediaProjection mediaProjection;
private VirtualDisplay virtualDisplay
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (resultCode != RESULT_OK) {
return;
}
mediaProjection = projectionManager.getMediaProjection(resultCode, data);
if (mediaProjection != null) {
mediaProjection.registerCallback(new MediaProjectionCallback(), null);
virtualDisplay = mediaProjection.createVirtualDisplay("VirtualDisplay name", 화면 넓이, 화면 높이, 화면 density, flag, surface(화면을 출력할 곳), null /* Callbacks */, null /* Handler */);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
```
댓글