package com.xuqm.sdk.sample import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import com.xuqm.sdk.XuqmSDK import com.xuqm.sdk.im.ImSDK import com.xuqm.sdk.im.listener.ImEventListener import com.xuqm.sdk.im.model.ChatType import com.xuqm.sdk.im.model.ImMessage import com.xuqm.sdk.im.model.MsgType import com.xuqm.sdk.update.UpdateSDK import kotlinx.coroutines.launch import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) XuqmSDK.init( context = this, appKey = "ak_your_app_key", appSecret = "your_app_secret", apiBaseUrl = "http://10.0.2.2:8082", imBaseUrl = "ws://10.0.2.2:8082/ws/im", debug = true, ) setContent { MaterialTheme { Surface(modifier = Modifier.fillMaxSize()) { SdkDemoScreen() } } } } } @Composable fun SdkDemoScreen() { val context = LocalContext.current val scope = rememberCoroutineScope() val messages = remember { mutableStateListOf() } var msgInput by remember { mutableStateOf("") } var userId by remember { mutableStateOf("user_001") } var connected by remember { mutableStateOf(false) } var updateInfo by remember { mutableStateOf("") } val listener = remember { object : ImEventListener { override fun onConnected() { messages.add("[IM] 已连接"); connected = true } override fun onDisconnected(reason: String?) { messages.add("[IM] 断开: $reason"); connected = false } override fun onMessage(message: ImMessage) { messages.add("[消息] ${message.fromUserId}: ${message.content}") } } } Column( modifier = Modifier .fillMaxSize() .padding(16.dp) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(12.dp) ) { Text("XuqmSDK Demo", style = MaterialTheme.typography.headlineSmall) Card { Column(Modifier.padding(12.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { Text("IM 测试", style = MaterialTheme.typography.titleMedium) OutlinedTextField(value = userId, onValueChange = { userId = it }, label = { Text("UserId") }, modifier = Modifier.fillMaxWidth()) Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { Button(onClick = { ImSDK.addListener(listener) ImSDK.login("your_app_id", userId) }) { Text("连接") } Button(onClick = { ImSDK.disconnect(); connected = false }, colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)) { Text("断开") } } Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { OutlinedTextField(value = msgInput, onValueChange = { msgInput = it }, label = { Text("消息内容") }, modifier = Modifier.weight(1f)) Button(onClick = { if (msgInput.isNotBlank()) { ImSDK.sendMessage("user_002", ChatType.SINGLE, MsgType.TEXT, msgInput) msgInput = "" } }) { Text("发送") } } } } Card { Column(Modifier.padding(12.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { Text("版本更新", style = MaterialTheme.typography.titleMedium) Button(onClick = { scope.launch { val info = UpdateSDK.checkUpdate(context, "your_app_id") updateInfo = if (info?.needsUpdate == true) "发现新版本: ${info.versionName}" else "已是最新版本" } }) { Text("检查更新") } if (updateInfo.isNotBlank()) Text(updateInfo) } } Card { Column(Modifier.padding(12.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { Text("Sentry 测试", style = MaterialTheme.typography.titleMedium) Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { Button(onClick = { scope.launch { val result = withContext(Dispatchers.IO) { val eventId = Sentry.captureException( IllegalStateException("This app uses Sentry! :)") ) { eventScope -> eventScope.setTag("source", "main_activity_button") eventScope.setLevel(SentryLevel.ERROR) } val flushed = Sentry.flush(5_000) eventId to flushed } messages.add("[Sentry] 已发送: ${result.first}, flush=${result.second}") } }) { Text("上报异常") } Button(onClick = { throw RuntimeException("Uncaught crash test for Sentry") }, colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)) { Text("闪退测试") } } } } Card { Column(Modifier.padding(12.dp)) { Text("消息日志", style = MaterialTheme.typography.titleMedium) Spacer(Modifier.height(8.dp)) messages.forEach { msg -> Text(msg, style = MaterialTheme.typography.bodySmall) } } } } }