Browse Source

fix: resolve LongScreenshotCapture initialization issue

- Extended ScreenCaptureManager interface with getMediaProjection() and getScreenDensity()
- Implemented MediaProjection sharing in ScreenCaptureManagerImpl
- Fixed LongScreenshotCapture initialization with proper MediaProjection access
- Simplified captureFrame() method to directly acquire images from ImageReader
- Added proper initialization checks and error handling in ScreenCaptureService

This resolves the "Cannot start collection - not initialized" error by ensuring
LongScreenshotCapture is properly initialized with the shared MediaProjection
instance during ScreenCaptureService startup.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
feature/pgh-30-long-screenshot-capture
Dan 5 months ago
parent
commit
2d98941f63
  1. 44
      app/src/main/java/com/quillstudios/pokegoalshelper/ScreenCaptureService.kt
  2. 46
      app/src/main/java/com/quillstudios/pokegoalshelper/capture/LongScreenshotCapture.kt
  3. 12
      app/src/main/java/com/quillstudios/pokegoalshelper/capture/ScreenCaptureManager.kt
  4. 10
      app/src/main/java/com/quillstudios/pokegoalshelper/capture/ScreenCaptureManagerImpl.kt

44
app/src/main/java/com/quillstudios/pokegoalshelper/ScreenCaptureService.kt

@ -335,13 +335,26 @@ class ScreenCaptureService : Service() {
// Initialize long screenshot system with shared MediaProjection
val screenDimensions = screenCaptureManager.getScreenDimensions()
if (screenDimensions != null) {
val mediaProjection = screenCaptureManager.getMediaProjection()
val screenDensity = screenCaptureManager.getScreenDensity()
if (screenDimensions != null && mediaProjection != null) {
val (screenWidth, screenHeight) = screenDimensions
longScreenshotCapture = LongScreenshotCapture(this, handler)
// Get MediaProjection from screen capture manager (we'll need to add this method)
// For now, we'll initialize it later when we start long screenshot
PGHLog.i(TAG, "✅ Long screenshot system prepared")
// Initialize with the shared MediaProjection
val initialized = longScreenshotCapture!!.initialize(
mediaProjection, screenWidth, screenHeight, screenDensity
)
if (initialized) {
PGHLog.i(TAG, "✅ Long screenshot system initialized successfully")
} else {
PGHLog.e(TAG, "❌ Failed to initialize long screenshot system")
longScreenshotCapture = null
}
} else {
PGHLog.w(TAG, "⚠️ Cannot initialize long screenshot - missing MediaProjection or screen dimensions")
}
PGHLog.d(TAG, "Screen capture setup complete")
@ -1236,22 +1249,6 @@ class ScreenCaptureService : Service() {
{
PGHLog.i(TAG, "🚀 Starting long screenshot collection")
val screenDimensions = screenCaptureManager.getScreenDimensions()
if (screenDimensions == null)
{
PGHLog.e(TAG, "❌ Cannot start long screenshot - no screen dimensions")
enhancedFloatingFAB?.exitLongScreenshotModeExternal()
return
}
val (screenWidth, screenHeight) = screenDimensions
// We need to get the MediaProjection from the screen capture manager
// For now, we'll create a simple workaround by accessing the existing setup
// In a real implementation, we'd need to extend ScreenCaptureManager interface
// Initialize long screenshot capture with mock MediaProjection for now
// This will work because we're using the same MediaProjection instance
longScreenshotCapture?.let { capture ->
// Set up callbacks
capture.setProgressCallback { count ->
@ -1268,13 +1265,18 @@ class ScreenCaptureService : Service() {
}
}
// Start collection (we'll initialize the MediaProjection when we implement getMediaProjection)
// Start collection
val started = capture.startCollection()
if (!started)
{
PGHLog.e(TAG, "❌ Failed to start long screenshot collection")
enhancedFloatingFAB?.exitLongScreenshotModeExternal()
} else {
PGHLog.i(TAG, "✅ Long screenshot collection started successfully")
}
} ?: run {
PGHLog.e(TAG, "❌ Long screenshot system not initialized")
enhancedFloatingFAB?.exitLongScreenshotModeExternal()
}
}

46
app/src/main/java/com/quillstudios/pokegoalshelper/capture/LongScreenshotCapture.kt

@ -192,43 +192,19 @@ class LongScreenshotCapture(
{
PGHLog.d(TAG, "📸 Triggering manual frame capture")
// The capture will be handled by onImageAvailableListener
// We just need to trigger it by accessing the ImageReader
val latch = CountDownLatch(1)
var captureSuccess = false
// Force a capture by accessing the ImageReader
// The VirtualDisplay should automatically provide images to the ImageReader
imageReader?.acquireLatestImage()?.let { image ->
PGHLog.d(TAG, "📸 Image acquired from ImageReader, processing...")
handler.post {
try
{
// Force a capture by accessing the latest image
imageReader?.acquireLatestImage()?.let { image ->
// This will be processed by onImageAvailableListener
image.close()
captureSuccess = true
}
}
catch (e: Exception)
{
PGHLog.e(TAG, "Error triggering frame capture", e)
}
finally
{
latch.countDown()
// Process the image in a coroutine
captureScope.launch {
processImageAsync(image)
}
}
// Wait for capture to complete
val completed = latch.await(CAPTURE_TIMEOUT_MS, TimeUnit.MILLISECONDS)
if (!completed)
{
PGHLog.e(TAG, "⏱️ Frame capture timed out")
errorCallback?.invoke("Capture timed out")
false
}
else
{
captureSuccess
return true
} ?: run {
PGHLog.w(TAG, "⚠️ No image available from ImageReader")
return false
}
}

12
app/src/main/java/com/quillstudios/pokegoalshelper/capture/ScreenCaptureManager.kt

@ -39,6 +39,18 @@ interface ScreenCaptureManager
*/
fun getScreenDimensions(): Pair<Int, Int>?
/**
* Get the current MediaProjection instance for sharing with other capture systems.
* @return MediaProjection instance or null if not available
*/
fun getMediaProjection(): android.media.projection.MediaProjection?
/**
* Get the current screen density.
* @return Screen density or 0 if not initialized
*/
fun getScreenDensity(): Int
/**
* Clean up all resources. Should be called when manager is no longer needed.
*/

10
app/src/main/java/com/quillstudios/pokegoalshelper/capture/ScreenCaptureManagerImpl.kt

@ -207,6 +207,16 @@ class ScreenCaptureManagerImpl(
}
}
override fun getMediaProjection(): MediaProjection?
{
return mediaProjection
}
override fun getScreenDensity(): Int
{
return screenDensity
}
override fun release()
{
Log.d(TAG, "Releasing ScreenCaptureManager")

Loading…
Cancel
Save