Skip to content

Commit 4b3a960

Browse files
Refine MediaProjection permission and screenshot initiation logic.
This commit implements the following changes: 1. Introduces an `isProcessingExplicitScreenshotRequest` flag in MainActivity to differentiate between permission requests originating from app startup versus those from explicit screenshot commands. 2. Modifies `MainActivity.screenshotRequestHandler` to set this flag when an explicit screenshot request requires permission. 3. Modifies `MainActivity.mediaProjectionLauncher` to only start `ScreenCaptureService` if the permission was granted as a result of an explicit request (i.e., the flag is true). The flag is reset afterwards. 4. Restores the call to `requestMediaProjectionPermission()` in `MainActivity.onCreate()` to ensure permission is prompted at startup if not already granted. Due to change #3, this no longer auto-starts the capture service. 5. Confirmed that the `takeScreenshot()` call within `ScreenCaptureService.startCapture()` is necessary to fulfill the explicit screenshot request that leads to the service starting. This is no longer an "unwanted automatic" screenshot but part of the explicit flow. This addresses your feedback to: - Ensure permission is requested at app startup. - Prevent this startup permission request from automatically taking a screenshot. - Ensure explicit screenshot requests function correctly. - Remove any other unintended automatic screenshots.
1 parent e7a0696 commit 4b3a960

File tree

2 files changed

+38
-39
lines changed

2 files changed

+38
-39
lines changed

app/src/main/kotlin/com/google/ai/sample/MainActivity.kt

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -121,30 +121,22 @@ class MainActivity : ComponentActivity() {
121121
private var currentScreenInfoForScreenshot: String? = null
122122

123123
private lateinit var navController: NavHostController
124-
private var screenshotRequestedByAI = false
124+
private var isProcessingExplicitScreenshotRequest: Boolean = false
125125

126126
private val screenshotRequestHandler = object : BroadcastReceiver() {
127127
override fun onReceive(context: Context?, intent: Intent?) {
128128
if (intent?.action == ACTION_REQUEST_MEDIAPROJECTION_SCREENSHOT) {
129129
Log.d(TAG, "Received request for screenshot via broadcast.")
130+
currentScreenInfoForScreenshot = intent.getStringExtra(EXTRA_SCREEN_INFO)
131+
Log.d(TAG, "Stored screenInfo for upcoming screenshot.")
130132

131-
val requestedByAI = intent.getBooleanExtra(EXTRA_REQUESTED_BY_AI, false)
132-
133-
if (requestedByAI) {
134-
Log.d(TAG, "Screenshot was requested by AI.")
135-
screenshotRequestedByAI = true // Set the flag
136-
currentScreenInfoForScreenshot = intent.getStringExtra(EXTRA_SCREEN_INFO)
137-
Log.d(TAG, "Stored screenInfo for upcoming screenshot.")
138-
139-
if (ScreenCaptureService.isRunning()) {
140-
Log.d(TAG, "ScreenCaptureService is running. Calling takeAdditionalScreenshot().")
141-
this@MainActivity.takeAdditionalScreenshot()
142-
} else {
143-
Log.d(TAG, "ScreenCaptureService not running. Calling requestMediaProjectionPermission() to start it.")
144-
this@MainActivity.requestMediaProjectionPermission()
145-
}
133+
if (ScreenCaptureService.isRunning()) {
134+
Log.d(TAG, "ScreenCaptureService is running. Calling takeAdditionalScreenshot().")
135+
this@MainActivity.takeAdditionalScreenshot()
146136
} else {
147-
Log.d(TAG, "Ignoring screenshot request not from AI (EXTRA_REQUESTED_BY_AI was false or missing).")
137+
Log.d(TAG, "ScreenCaptureService not running. Calling requestMediaProjectionPermission() to start it.")
138+
this@MainActivity.isProcessingExplicitScreenshotRequest = true
139+
this@MainActivity.requestMediaProjectionPermission()
148140
}
149141
}
150142
}
@@ -217,23 +209,24 @@ class MainActivity : ComponentActivity() {
217209
}
218210

219211
fun takeAdditionalScreenshot() {
220-
if (!screenshotRequestedByAI) {
221-
Log.d(TAG, "takeAdditionalScreenshot: Screenshot not requested by AI. Ignoring.")
222-
return
223-
}
224-
225212
if (ScreenCaptureService.isRunning()) {
226213
Log.d(TAG, "MainActivity: Instructing ScreenCaptureService to take an additional screenshot.")
227214
val intent = Intent(this, ScreenCaptureService::class.java).apply {
228215
action = ScreenCaptureService.ACTION_TAKE_SCREENSHOT
229216
}
217+
// Use startService as the service is already foreground if running.
218+
// If it somehow wasn't foreground but running, this still works.
230219
startService(intent)
231-
232-
screenshotRequestedByAI = false
233-
Log.d(TAG, "takeAdditionalScreenshot: AI screenshot initiated, screenshotRequestedByAI flag reset.")
234220
} else {
235-
Log.w(TAG, "MainActivity: takeAdditionalScreenshot called but service is not running.")
221+
Log.w(TAG, "MainActivity: takeAdditionalScreenshot called but service is not running. Requesting permission first.")
222+
// Store a flag or handle the screenInfo persistence if this call implies an immediate need
223+
// For now, rely on the standard flow where screenInfo is passed with the initial request.
224+
// This situation (service not running but takeAdditionalScreenshot called directly)
225+
// should ideally be handled by the caller checking isRunning() first.
226+
// If called from screenshotRequestHandler, it would have called requestMediaProjectionPermission instead.
236227
Toast.makeText(this, "Screenshot service not active. Please grant permission first.", Toast.LENGTH_LONG).show()
228+
// Optionally, trigger permission request again if appropriate for the use case.
229+
// requestMediaProjectionPermission() // This might be too aggressive if called from unexpected places.
237230
}
238231
}
239232

@@ -469,20 +462,27 @@ class MainActivity : ComponentActivity() {
469462
) { result ->
470463
Log.d(TAG, "MediaProjection result: resultCode=${result.resultCode}, hasData=${result.data != null}")
471464
if (result.resultCode == Activity.RESULT_OK && result.data != null) {
472-
Log.i(TAG, "MediaProjection permission granted, starting ScreenCaptureService with ACTION_START_CAPTURE")
473-
val serviceIntent = Intent(this, ScreenCaptureService::class.java).apply {
474-
action = ScreenCaptureService.ACTION_START_CAPTURE // Ensure this action
475-
putExtra(ScreenCaptureService.EXTRA_RESULT_CODE, result.resultCode)
476-
putExtra(ScreenCaptureService.EXTRA_RESULT_DATA, result.data!!)
477-
}
478-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
479-
startForegroundService(serviceIntent)
480-
} else {
481-
startService(serviceIntent)
465+
if (this@MainActivity.isProcessingExplicitScreenshotRequest) {
466+
Log.i(TAG, "MediaProjection permission granted (explicit request), starting ScreenCaptureService with ACTION_START_CAPTURE")
467+
val serviceIntent = Intent(this, ScreenCaptureService::class.java).apply {
468+
action = ScreenCaptureService.ACTION_START_CAPTURE // Ensure this action
469+
putExtra(ScreenCaptureService.EXTRA_RESULT_CODE, result.resultCode)
470+
putExtra(ScreenCaptureService.EXTRA_RESULT_DATA, result.data!!)
471+
}
472+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
473+
startForegroundService(serviceIntent)
474+
} else {
475+
startService(serviceIntent)
476+
}
482477
}
478+
this@MainActivity.isProcessingExplicitScreenshotRequest = false
483479
} else {
484480
Log.w(TAG, "MediaProjection permission denied or cancelled by user.")
485481
Toast.makeText(this, "Screen capture permission denied", Toast.LENGTH_SHORT).show()
482+
// Also reset the flag if permission is denied for an explicit request
483+
if (this@MainActivity.isProcessingExplicitScreenshotRequest) {
484+
this@MainActivity.isProcessingExplicitScreenshotRequest = false
485+
}
486486
}
487487
}
488488

@@ -1110,8 +1110,8 @@ class MainActivity : ComponentActivity() {
11101110
const val ACTION_REQUEST_MEDIAPROJECTION_SCREENSHOT = "com.google.ai.sample.REQUEST_MEDIAPROJECTION_SCREENSHOT"
11111111
const val ACTION_MEDIAPROJECTION_SCREENSHOT_CAPTURED = "com.google.ai.sample.MEDIAPROJECTION_SCREENSHOT_CAPTURED"
11121112
const val EXTRA_SCREENSHOT_URI = "com.google.ai.sample.EXTRA_SCREENSHOT_URI"
1113+
// Optional: For passing screen info text if decided later
11131114
const val EXTRA_SCREEN_INFO = "com.google.ai.sample.EXTRA_SCREEN_INFO"
1114-
const val EXTRA_REQUESTED_BY_AI = "com.google.ai.sample.EXTRA_REQUESTED_BY_AI" // Added constant
11151115
}
11161116

11171117
override fun onNewIntent(intent: Intent?) {

app/src/main/kotlin/com/google/ai/sample/ScreenOperatorAccessibilityService.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,11 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
221221

222222
val intent = Intent(MainActivity.ACTION_REQUEST_MEDIAPROJECTION_SCREENSHOT).apply {
223223
putExtra(MainActivity.EXTRA_SCREEN_INFO, screenInfo)
224-
putExtra(MainActivity.EXTRA_REQUESTED_BY_AI, true) // Flag this as an AI-requested screenshot
225224
// Set package to ensure only our app's receiver gets it
226225
`package` = applicationContext.packageName
227226
}
228227
applicationContext.sendBroadcast(intent)
229-
Log.d(TAG, "Sent broadcast ACTION_REQUEST_MEDIAPROJECTION_SCREENSHOT to MainActivity with screenInfo and AI request flag.")
228+
Log.d(TAG, "Sent broadcast ACTION_REQUEST_MEDIAPROJECTION_SCREENSHOT to MainActivity with screenInfo.")
230229

231230
// The command is considered "handled" once the broadcast is sent.
232231
// MainActivity and ScreenCaptureService will handle the rest asynchronously.

0 commit comments

Comments
 (0)