@ -22,9 +22,10 @@ import android.view.WindowManager
class ScreenCaptureManagerImpl (
private val context : Context ,
private val handler : Handler
) : ScreenCaptureManager {
companion object {
) : ScreenCaptureManager
{
companion object
{
private const val TAG = " ScreenCaptureManager "
private const val BUFFER_COUNT = 3
}
@ -41,60 +42,74 @@ class ScreenCaptureManagerImpl(
private var imageCallback : ( ( Image ) -> Unit ) ? = null
private var isActive = false
init {
init
{
mediaProjectionManager = context . getSystemService ( Context . MEDIA_PROJECTION_SERVICE ) as MediaProjectionManager
initializeScreenMetrics ( )
}
private fun initializeScreenMetrics ( ) {
val displayMetrics = DisplayMetrics ( )
val windowManager = context . getSystemService ( Context . WINDOW_SERVICE ) as WindowManager
windowManager . defaultDisplay . getMetrics ( displayMetrics )
private fun initializeScreenMetrics ( )
{
val display_metrics = DisplayMetrics ( )
val window_manager = context . getSystemService ( Context . WINDOW_SERVICE ) as WindowManager
window_manager . defaultDisplay . getMetrics ( display_metrics )
screenWidth = displayM etrics . widthPixels
screenHeight = displayM etrics . heightPixels
screenDensity = displayM etrics . densityDpi
screenWidth = display_m etrics . widthPixels
screenHeight = display_m etrics . heightPixels
screenDensity = display_m etrics . densityDpi
Log . d ( TAG , " Screen metrics initialized: ${screenWidth} x ${screenHeight} , density: $screenDensity " )
}
private val mediaProjectionCallback = object : MediaProjection . Callback ( ) {
override fun onStop ( ) {
private val mediaProjectionCallback = object : MediaProjection . Callback ( )
{
override fun onStop ( )
{
Log . d ( TAG , " MediaProjection stopped " )
stopCapture ( )
}
override fun onCapturedContentResize ( width : Int , height : Int ) {
override fun onCapturedContentResize ( width : Int , height : Int )
{
Log . d ( TAG , " Screen size changed: ${width} x ${height} " )
}
override fun onCapturedContentVisibilityChanged ( isVisible : Boolean ) {
override fun onCapturedContentVisibilityChanged ( isVisible : Boolean )
{
Log . d ( TAG , " Content visibility changed: $isVisible " )
}
}
private val onImageAvailableListener = ImageReader . OnImageAvailableListener { reader ->
try {
val image = reader . acquireLatestImage ( )
if ( image != null ) {
imageCallback ?. invoke ( image )
try
{
val captured_image = reader . acquireLatestImage ( )
if ( captured_image != null )
{
imageCallback ?. invoke ( captured_image )
}
} catch ( e : Exception ) {
}
catch ( e : Exception )
{
Log . e ( TAG , " Error in onImageAvailableListener " , e )
}
}
override fun startCapture ( resultData : Intent ) : Boolean {
if ( isActive ) {
override fun startCapture ( resultData : Intent ) : Boolean
{
if ( isActive )
{
Log . w ( TAG , " Capture already active " )
return true
}
try {
try
{
Log . d ( TAG , " Starting screen capture " )
mediaProjection = mediaProjectionManager ?. getMediaProjection ( Activity . RESULT_OK , resultData )
if ( mediaProjection == null ) {
if ( mediaProjection == null )
{
Log . e ( TAG , " Failed to get MediaProjection " )
return false
}
@ -118,7 +133,8 @@ class ScreenCaptureManagerImpl(
null
)
if ( virtualDisplay == null ) {
if ( virtualDisplay == null )
{
Log . e ( TAG , " Failed to create VirtualDisplay " )
cleanupResources ( )
return false
@ -127,16 +143,19 @@ class ScreenCaptureManagerImpl(
isActive = true
Log . d ( TAG , " Screen capture started successfully " )
return true
} catch ( e : Exception ) {
}
catch ( e : Exception )
{
Log . e ( TAG , " Error starting screen capture " , e )
cleanupResources ( )
return false
}
}
override fun stopCapture ( ) {
if ( !is Active ) {
override fun stopCapture ( )
{
if ( !is Active )
{
Log . d ( TAG , " Capture not active, nothing to stop " )
return
}
@ -147,37 +166,49 @@ class ScreenCaptureManagerImpl(
Log . d ( TAG , " Screen capture stopped " )
}
private fun cleanupResources ( ) {
try {
private fun cleanupResources ( )
{
try
{
virtualDisplay ?. release ( )
imageReader ?. close ( )
mediaProjection ?. unregisterCallback ( mediaProjectionCallback )
mediaProjection ?. stop ( )
} catch ( e : Exception ) {
}
catch ( e : Exception )
{
Log . e ( TAG , " Error during cleanup " , e )
} finally {
}
finally
{
virtualDisplay = null
imageReader = null
mediaProjection = null
}
}
override fun setImageCallback ( callback : ( Image ) -> Unit ) {
override fun setImageCallback ( callback : ( Image ) -> Unit )
{
this . imageCallback = callback
Log . d ( TAG , " Image callback set " )
}
override fun isCapturing ( ) : Boolean = isActive
override fun getScreenDimensions ( ) : Pair < Int , Int > ? {
return if ( screenWidth > 0 && screenHeight > 0 ) {
override fun getScreenDimensions ( ) : Pair < Int , Int > ?
{
return if ( screenWidth > 0 && screenHeight > 0 )
{
Pair ( screenWidth , screenHeight )
} else {
}
else
{
null
}
}
override fun release ( ) {
override fun release ( )
{
Log . d ( TAG , " Releasing ScreenCaptureManager " )
stopCapture ( )
imageCallback = null