Skip to content

Commit 5761192

Browse files
All fixes validated in Kritikermodus
1 parent 0162b8d commit 5761192

4 files changed

Lines changed: 47 additions & 94 deletions

File tree

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

Lines changed: 29 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,18 @@ class MainActivity : ComponentActivity() {
518518
ActivityResultContracts.StartActivityForResult()
519519
) { result ->
520520
if (result.resultCode == Activity.RESULT_OK && result.data != null) {
521-
Log.i(TAG, "WebRTC MediaProjection permission granted.")
521+
Log.i(TAG, "WebRTC MediaProjection permission granted. Starting keep-alive service.")
522+
523+
// Task 4: Keep Service Alive to satisfy Android 14 MediaProjection requirements
524+
val serviceIntent = Intent(this, ScreenCaptureService::class.java).apply {
525+
action = ScreenCaptureService.ACTION_KEEP_ALIVE_FOR_WEBRTC
526+
}
527+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
528+
startForegroundService(serviceIntent)
529+
} else {
530+
startService(serviceIntent)
531+
}
532+
522533
onWebRtcMediaProjectionResult?.invoke(result.resultCode, result.data!!)
523534
onWebRtcMediaProjectionResult = null
524535
} else {
@@ -654,7 +665,22 @@ class MainActivity : ComponentActivity() {
654665
Button(
655666
onClick = {
656667
showPaymentMethodDialog = false
657-
showPayPalWebViewDialog = true
668+
669+
// Generate Short UUID
670+
val shortId = java.util.UUID.randomUUID().toString().substring(0, 8)
671+
672+
// Save it to SharedPreferences
673+
val ctx = this@MainActivity
674+
ctx.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
675+
.edit()
676+
.putString("payment_support_id", shortId)
677+
.apply()
678+
679+
Toast.makeText(ctx, "Your Support ID is: $shortId", Toast.LENGTH_LONG).show()
680+
681+
val url = "https://www.paypal.com/webapps/billing/subscriptions?plan_id=P-5J921557TD348880GNGUCRSI&custom_id=$shortId"
682+
val intent = Intent(Intent.ACTION_VIEW, android.net.Uri.parse(url))
683+
ctx.startActivity(intent)
658684
},
659685
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
660686
) {
@@ -680,82 +706,7 @@ class MainActivity : ComponentActivity() {
680706
)
681707
}
682708

683-
// Task 6: PayPal WebView Dialog
684-
if (showPayPalWebViewDialog) {
685-
Dialog(
686-
onDismissRequest = { showPayPalWebViewDialog = false },
687-
properties = DialogProperties(usePlatformDefaultWidth = false)
688-
) {
689-
Card(modifier = Modifier.fillMaxSize().padding(16.dp)) {
690-
Column(modifier = Modifier.fillMaxSize()) {
691-
Row(
692-
modifier = Modifier.fillMaxWidth().padding(8.dp),
693-
horizontalArrangement = Arrangement.SpaceBetween,
694-
verticalAlignment = Alignment.CenterVertically
695-
) {
696-
Text("PayPal Subscription", style = MaterialTheme.typography.titleMedium)
697-
TextButton(onClick = { showPayPalWebViewDialog = false }) {
698-
Text("Close")
699-
}
700-
}
701-
702-
androidx.compose.ui.viewinterop.AndroidView(
703-
factory = { ctx ->
704-
android.webkit.WebView(ctx).apply {
705-
settings.javaScriptEnabled = true
706-
settings.domStorageEnabled = true
707-
webViewClient = android.webkit.WebViewClient()
708-
709-
// Generate Short UUID
710-
val shortId = java.util.UUID.randomUUID().toString().substring(0, 8)
711-
712-
// Save it to SharedPreferences
713-
ctx.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
714-
.edit()
715-
.putString("payment_support_id", shortId)
716-
.apply()
717-
718-
val html = """
719-
<!DOCTYPE html>
720-
<html>
721-
<head>
722-
<meta name="viewport" content="width=device-width, initial-scale=1">
723-
</head>
724-
<body>
725-
<div id="paypal-button-container-P-5J921557TD348880GNGUCRSI"></div>
726-
<script src="https://www.paypal.com/sdk/js?client-id=AQ52P9G85S3RCHw7lWnEDH_Pudk-5JdE8S6gBfS72jWwMng-xR-0qNrtmS8Mv5RtdK--a1cZ0G-12_rZ&vault=true&intent=subscription" data-sdk-integration-source="button-factory"></script>
727-
<script>
728-
paypal.Buttons({
729-
style: {
730-
shape: 'rect',
731-
color: 'gold',
732-
layout: 'vertical',
733-
label: 'subscribe'
734-
},
735-
createSubscription: function(data, actions) {
736-
return actions.subscription.create({
737-
'plan_id': 'P-5J921557TD348880GNGUCRSI',
738-
'custom_id': '$shortId'
739-
});
740-
},
741-
onApprove: function(data, actions) {
742-
alert('Thank you for your subscription! Your Support ID is: $shortId');
743-
}
744-
}).render('#paypal-button-container-P-5J921557TD348880GNGUCRSI');
745-
</script>
746-
</body>
747-
</html>
748-
""".trimIndent()
749-
750-
loadDataWithBaseURL("https://www.paypal.com", html, "text/html", "UTF-8", null)
751-
}
752-
},
753-
modifier = Modifier.fillMaxSize()
754-
)
755-
}
756-
}
757-
}
758-
}
709+
759710
}
760711
}
761712
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ fun MenuScreen(
515515
)
516516
} else {
517517
Text(
518-
text = "Support Improvements\n \uD83C\uDF89",
518+
text = "Support Improvements\n \uD83C\uDF89",
519519
style = MaterialTheme.typography.titleMedium,
520520
modifier = Modifier.weight(1f)
521521
)

app/src/main/kotlin/com/google/ai/sample/feature/multimodal/PhotoReasoningScreen.kt

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -501,12 +501,13 @@ fun PhotoReasoningScreen(
501501

502502
// Task 18: Always show Stop button for offline model to allow manual closing
503503
val showStopButton = modelName == "gemma-3n-e4b-it" || uiState is PhotoReasoningUiState.Loading
504-
Card(modifier = Modifier.fillMaxWidth()) {
505-
Column(modifier = Modifier.fillMaxWidth()) {
506-
val isGenerating = (uiState is PhotoReasoningUiState.Loading) && (messages.lastOrNull()?.isPending == true)
507-
val showTextFieldRow = !isGenerating
508-
509-
if (showTextFieldRow) {
504+
505+
val isGenerating = (uiState is PhotoReasoningUiState.Loading) && (messages.lastOrNull()?.isPending == true)
506+
val showTextFieldRow = !isGenerating
507+
508+
if (showTextFieldRow) {
509+
Card(modifier = Modifier.fillMaxWidth()) {
510+
Column(modifier = Modifier.fillMaxWidth()) {
510511
Row(modifier = Modifier.padding(top = 16.dp)) {
511512
Column(modifier = Modifier.padding(all = 4.dp).align(Alignment.CenterVertically)) {
512513
IconButton(onClick = { pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) }, modifier = Modifier.padding(bottom = 4.dp)) {
@@ -569,14 +570,15 @@ fun PhotoReasoningScreen(
569570
LazyRow(modifier = Modifier.padding(all = 8.dp)) {
570571
items(imageUris) { uri -> AsyncImage(uri, null, Modifier.padding(4.dp).requiredSize(72.dp)) }
571572
}
572-
}
573-
574-
// Task 1: Stop button is independent and below the text field
575-
if (showStopButton) {
576-
StopButton(onClick = onStopClicked)
577-
}
578-
} // Closes Column
579-
} // Closes Card
573+
} // Closes Column
574+
} // Closes Card
575+
}
576+
577+
// Task 1: Stop button is independent and below the text field
578+
if (showStopButton) {
579+
Spacer(modifier = Modifier.height(8.dp))
580+
StopButton(onClick = onStopClicked)
581+
}
580582
}
581583

582584
// Popups remain outside the main content flow, attached to the screen Column

app/src/main/kotlin/com/google/ai/sample/feature/multimodal/PhotoReasoningViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ class PhotoReasoningViewModel(
10591059
liveApiManager?.close()
10601060
}
10611061

1062-
// Task 18: Close offline model ONLY if no inference/commands are running
1062+
// Close offline model ONLY if no inference/commands are running
10631063
val isReasoningActive = currentReasoningJob?.isActive == true
10641064
val isCommandProcessingActive = commandProcessingJob?.isActive == true
10651065
if (!isReasoningActive && !isCommandProcessingActive && com.google.ai.sample.GenerativeAiViewModelFactory.getCurrentModel() == ModelOption.GEMMA_3N_E4B_IT) {

0 commit comments

Comments
 (0)