Skip to content

Commit 236ccb1

Browse files
Add files via upload
1 parent 038b1c4 commit 236ccb1

1 file changed

Lines changed: 53 additions & 9 deletions

File tree

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

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ import android.provider.MediaStore
1818
import android.view.accessibility.AccessibilityEvent
1919
import android.view.accessibility.AccessibilityNodeInfo
2020
import android.util.Log
21+
import android.widget.Toast
2122
import androidx.annotation.RequiresApi
2223
import com.google.ai.sample.util.Command
24+
import kotlinx.coroutines.CoroutineScope
25+
import kotlinx.coroutines.Dispatchers
26+
import kotlinx.coroutines.launch
2327
import java.io.File
2428
import java.util.concurrent.TimeUnit
2529

@@ -33,7 +37,7 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
3337
private var shouldTakeScreenshot = false
3438

3539
// Callback to be executed after screenshot is taken
36-
private var onScreenshotTaken: (() -> Unit)? = null
40+
private var onScreenshotTaken: ((Uri?) -> Unit)? = null
3741

3842
// Instance of the service
3943
private var instance: ScreenOperatorAccessibilityService? = null
@@ -45,7 +49,7 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
4549
private var screenshotTimestamp: Long = 0
4650

4751
// Method to trigger screenshot from outside the service
48-
fun takeScreenshot(callback: () -> Unit) {
52+
fun takeScreenshot(callback: (Uri?) -> Unit) {
4953
Log.d(TAG, "takeScreenshot called")
5054
shouldTakeScreenshot = true
5155
onScreenshotTaken = callback
@@ -61,7 +65,7 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
6165
Log.e(TAG, "No service instance available. Make sure the accessibility service is enabled in settings.")
6266
// Still call the callback to prevent blocking the UI
6367
Handler(Looper.getMainLooper()).postDelayed({
64-
onScreenshotTaken?.invoke()
68+
onScreenshotTaken?.invoke(null)
6569
onScreenshotTaken = null
6670
}, 500)
6771
}
@@ -240,6 +244,44 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
240244
Log.d(TAG, "Executing tapAtCoordinates command: ${command.x}, ${command.y}")
241245
instance?.tapAtCoordinates(command.x, command.y)
242246
}
247+
is Command.TakeScreenshot -> {
248+
Log.d(TAG, "Executing takeScreenshot command")
249+
// Take a screenshot and add it to the current conversation
250+
takeScreenshotAndAddToConversation()
251+
}
252+
}
253+
}
254+
255+
// Take a screenshot and add it to the current conversation
256+
private fun takeScreenshotAndAddToConversation() {
257+
// Show a toast to indicate we're taking a screenshot
258+
instance?.applicationContext?.let { context ->
259+
Toast.makeText(context, "Taking screenshot...", Toast.LENGTH_SHORT).show()
260+
}
261+
262+
// Take the screenshot
263+
takeScreenshot { screenshotUri ->
264+
// This will be called after the screenshot is taken
265+
CoroutineScope(Dispatchers.Main).launch {
266+
if (screenshotUri != null) {
267+
Log.d(TAG, "Screenshot taken and will be added to conversation: $screenshotUri")
268+
269+
// Show a toast to indicate the screenshot was added
270+
instance?.applicationContext?.let { context ->
271+
Toast.makeText(context, "Screenshot added to conversation", Toast.LENGTH_SHORT).show()
272+
}
273+
274+
// The PhotoReasoningViewModel will handle adding the screenshot to the conversation
275+
// in its next interaction with the AI
276+
} else {
277+
Log.e(TAG, "Failed to take screenshot or get URI")
278+
279+
// Show a toast to indicate the failure
280+
instance?.applicationContext?.let { context ->
281+
Toast.makeText(context, "Failed to take screenshot", Toast.LENGTH_SHORT).show()
282+
}
283+
}
284+
}
243285
}
244286
}
245287
}
@@ -283,15 +325,17 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
283325
// Reset the flag
284326
shouldTakeScreenshot = false
285327

286-
// Execute the callback
287-
Log.d(TAG, "Executing screenshot callback")
288-
onScreenshotTaken?.invoke()
328+
// Get the latest screenshot URI
329+
val screenshotUri = getLatestScreenshotUri()
330+
331+
// Execute the callback with the screenshot URI
332+
Log.d(TAG, "Executing screenshot callback with URI: $screenshotUri")
333+
onScreenshotTaken?.invoke(screenshotUri)
289334
onScreenshotTaken = null
290335

291336
// Broadcast that a screenshot was taken to refresh media scanner
292-
val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
293-
getLatestScreenshotUri()?.let { uri ->
294-
Log.d(TAG, "Screenshot URI: $uri")
337+
screenshotUri?.let { uri ->
338+
val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
295339
intent.data = uri
296340
sendBroadcast(intent)
297341
}

0 commit comments

Comments
 (0)