diff --git a/app/build.gradle b/app/build.gradle index 3d4b0e6..53d8295 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,6 @@ plugins { alias(libs.plugins.android.application) + alias(libs.plugins.compose.compiler) } android { @@ -26,9 +27,21 @@ android { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 } + buildFeatures { + compose true + } } dependencies { + implementation libs.androidx.core.ktx + implementation libs.androidx.lifecycle.runtime.ktx + implementation libs.androidx.activity.compose + implementation platform(libs.androidx.compose.bom) + implementation libs.androidx.compose.ui + implementation libs.androidx.compose.ui.graphics + implementation libs.androidx.compose.ui.tooling.preview + implementation libs.androidx.compose.material3 + implementation libs.appcompat implementation libs.material testImplementation libs.junit diff --git a/app/src/main/java/com/kimgo/posefit/MainActivity.kt b/app/src/main/java/com/kimgo/posefit/MainActivity.kt index cdd24e0..81d8660 100644 --- a/app/src/main/java/com/kimgo/posefit/MainActivity.kt +++ b/app/src/main/java/com/kimgo/posefit/MainActivity.kt @@ -1,41 +1,116 @@ package com.kimgo.posefit import android.Manifest +import android.content.Context import android.os.Bundle import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.* +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp import com.kimgo.posefit.sender.WebRtcSenderClient class MainActivity : ComponentActivity() { - private lateinit var webRtcClient: WebRtcSenderClient + private var webRtcClient: WebRtcSenderClient? = null private val requestPermission = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> if (granted) { - startWebRtc() + val url = getSavedSignalingUrl() + startWebRtc(url) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - requestPermission.launch(Manifest.permission.CAMERA) + setContent { + MaterialTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + ConfigScreen() + } + } + } } - private fun startWebRtc() { + @Composable + fun ConfigScreen() { + var url by remember { mutableStateOf(getSavedSignalingUrl()) } + var isStreaming by remember { mutableStateOf(false) } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(24.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = "PoseFit 配置", + style = MaterialTheme.typography.headlineMedium, + color = MaterialTheme.colorScheme.primary + ) + Spacer(modifier = Modifier.height(32.dp)) + TextField( + value = url, + onValueChange = { url = it }, + label = { Text("服务器地址 (ws://...)") }, + modifier = Modifier.fillMaxWidth(), + enabled = !isStreaming + ) + Spacer(modifier = Modifier.height(16.dp)) + Button( + onClick = { + if (isStreaming) { + stopWebRtc() + isStreaming = false + } else { + saveSignalingUrl(url) + requestPermission.launch(Manifest.permission.CAMERA) + isStreaming = true + } + }, + modifier = Modifier.fillMaxWidth() + ) { + Text(if (isStreaming) "停止推流" else "开始推流") + } + } + } + + private fun getSavedSignalingUrl(): String { + val prefs = getSharedPreferences("posefit_prefs", Context.MODE_PRIVATE) + return prefs.getString("signaling_url", "ws://192.168.110.240:8080") ?: "ws://192.168.110.240:8080" + } + + private fun saveSignalingUrl(url: String) { + val prefs = getSharedPreferences("posefit_prefs", Context.MODE_PRIVATE) + prefs.edit().putString("signaling_url", url).apply() + } + + private fun startWebRtc(url: String) { + webRtcClient?.release() webRtcClient = WebRtcSenderClient( context = this, - signalingUrl = "ws://192.168.110.240:8080" + signalingUrl = url ) + webRtcClient?.start() + } - webRtcClient.start() + private fun stopWebRtc() { + webRtcClient?.release() + webRtcClient = null } override fun onDestroy() { super.onDestroy() - if (::webRtcClient.isInitialized) { - webRtcClient.release() - } + stopWebRtc() } -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a997744..fc9b9cf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,11 @@ [versions] agp = "9.2.1" +kotlin = "2.0.0" +composeBom = "2024.02.00" +composeCompiler = "1.5.8" +activityCompose = "1.8.2" +coreKtx = "1.12.0" +lifecycleRuntimeKtx = "2.7.0" junit = "4.13.2" junitVersion = "1.1.5" espressoCore = "3.5.1" @@ -12,7 +18,18 @@ ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitV espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } +jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }