

























@@ -14,11 +14,14 @@ import ai.openclaw.app.ui.design.ClawStatusPill
1414import ai.openclaw.app.ui.design.ClawTextField
1515import ai.openclaw.app.ui.design.ClawTheme
1616import android.Manifest
17+import android.content.ClipData
18+import android.content.ClipboardManager
1719import android.content.Context
1820import android.content.Intent
1921import android.content.pm.PackageManager
2022import android.os.Build
2123import android.provider.Settings
24+import android.widget.Toast
2225import androidx.activity.compose.rememberLauncherForActivityResult
2326import androidx.activity.result.contract.ActivityResultContracts
2427import androidx.compose.foundation.BorderStroke
@@ -492,6 +495,7 @@ private fun V2GatewayRecoveryScreen(
492495modifier: Modifier = Modifier,
493496) {
494497val pairingRequired = gatewayStatusLooksLikePairing(statusText)
498+val context = LocalContext.current
495499PairingAutoRetryEffect(enabled = pairingRequired && attemptedConnect && !ready, onRetry = onAutoRetry)
496500497501ClawScaffold(modifier = modifier, contentPadding = PaddingValues(horizontal = 18.dp, vertical = 16.dp)) {
@@ -534,7 +538,7 @@ private fun V2GatewayRecoveryScreen(
534538Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
535539ClawPrimaryButton(text = if (ready) "Continue" else "Retry connection", icon = if (ready) Icons.Default.CheckCircle else Icons.Default.Refresh, onClick = if (ready) onContinue else onRetry, modifier = Modifier.fillMaxWidth())
536540V2OutlinedAction(title = "Edit connection", icon = Icons.Default.Edit, onClick = onEdit)
537-V2OutlinedAction(title = "Copy diagnostic", icon = Icons.Default.ContentCopy, onClick = {})
541+V2OutlinedAction(title = "Copy diagnostic", icon = Icons.Default.ContentCopy, onClick = { copyGatewayDiagnostic(context, statusText, serverName, remoteAddress, ready) })
538542 }
539543 }
540544 }
@@ -688,6 +692,26 @@ private fun V2TogglePill(
688692689693@Composable
690694private fun V2PermissionTopBar(onBack: () -> Unit) {
695+var showHelp by remember { mutableStateOf(false) }
696+if (showHelp) {
697+AlertDialog(
698+ onDismissRequest = { showHelp = false },
699+ containerColor = ClawTheme.colors.surfaceRaised,
700+ title = { Text("Permissions", style = ClawTheme.type.section, color = ClawTheme.colors.text) },
701+ text = {
702+Text(
703+"Choose what this phone can share with OpenClaw. You can change these later in Settings.",
704+ style = ClawTheme.type.body,
705+ color = ClawTheme.colors.textMuted,
706+ )
707+ },
708+ confirmButton = {
709+TextButton(onClick = { showHelp = false }) {
710+Text("Done")
711+ }
712+ },
713+ )
714+ }
691715Box(modifier = Modifier.fillMaxWidth().height(38.dp), contentAlignment = Alignment.Center) {
692716Surface(
693717 onClick = onBack,
@@ -706,7 +730,7 @@ private fun V2PermissionTopBar(onBack: () -> Unit) {
706730 maxLines = 1,
707731 )
708732Surface(
709- onClick = {},
733+ onClick = { showHelp = true },
710734 modifier = Modifier.align(Alignment.CenterEnd).size(28.dp),
711735 shape = CircleShape,
712736 color = Color.Transparent,
@@ -858,6 +882,26 @@ private fun recoveryGatewayDetail(
858882"Gateway unreachable"
859883 }
860884885+private fun copyGatewayDiagnostic(
886+context: Context,
887+statusText: String,
888+serverName: String?,
889+remoteAddress: String?,
890+ready: Boolean,
891+) {
892+val diagnostic =
893+listOf(
894+"OpenClaw Android gateway diagnostic",
895+"Status: $statusText",
896+"Gateway: ${serverName?.takeIf { it.isNotBlank() } ?: "Home Gateway"}",
897+"Address: ${remoteAddress?.takeIf { it.isNotBlank() } ?: "Not available"}",
898+"Ready: ${if (ready) "yes" else "no"}",
899+ ).joinToString("\n")
900+val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
901+ clipboard.setPrimaryClip(ClipData.newPlainText("OpenClaw gateway diagnostic", diagnostic))
902+Toast.makeText(context, "Diagnostic copied", Toast.LENGTH_SHORT).show()
903+}
904+861905private data class V2PermissionRowModel(
862906val title: String,
863907val subtitle: String,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。