2026-04-21 22:07:29 +08:00
|
|
|
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
|
2026-04-24 16:46:38 +08:00
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
|
import kotlinx.coroutines.withContext
|
2026-04-21 22:07:29 +08:00
|
|
|
|
|
|
|
|
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<String>() }
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-24 16:46:38 +08:00
|
|
|
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("闪退测试")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-21 22:07:29 +08:00
|
|
|
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) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|