集成 Timber 日志框架,降级 AGP/Gradle 适配 JDK 17,修复构建设置
- 新增 PosefitApplication 初始化 Timber DebugTree - WebRtcSenderClient/MainActivity/SimpleSdpObserver 添加 Timber 日志 - AGP 9.2.1 → 8.7.3,Gradle 9.4.1 → 8.11.1 适配 JDK 17 - compileSdk/targetSdk 恢复为 34,minSdk 保持 29 支持 Android 10 - 添加 android.useAndroidX=true 修复构建检查 - 删除 gradle-daemon-jvm.properties (JDK 21 残留配置) - 信令端口默认改为 8765
This commit is contained in:
@@ -29,6 +29,7 @@ android {
|
||||
}
|
||||
buildFeatures {
|
||||
compose true
|
||||
buildConfig true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +48,7 @@ dependencies {
|
||||
testImplementation libs.junit
|
||||
androidTestImplementation libs.espresso.core
|
||||
androidTestImplementation libs.ext.junit
|
||||
implementation libs.timber
|
||||
implementation "io.getstream:stream-webrtc-android:1.3.10"
|
||||
implementation "com.squareup.okhttp3:okhttp:4.12.0"
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:name=".PosefitApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.kimgo.posefit.sender.WebRtcSenderClient
|
||||
import timber.log.Timber
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
@@ -23,11 +24,14 @@ class MainActivity : ComponentActivity() {
|
||||
if (granted) {
|
||||
val url = getSavedSignalingUrl()
|
||||
startWebRtc(url)
|
||||
} else {
|
||||
Timber.w("Camera permission denied")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Timber.d("MainActivity onCreate")
|
||||
|
||||
setContent {
|
||||
MaterialTheme {
|
||||
@@ -87,7 +91,7 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
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"
|
||||
return prefs.getString("signaling_url", "ws://192.168.2.10:8765") ?: "ws://192.168.2.10:8765"
|
||||
}
|
||||
|
||||
private fun saveSignalingUrl(url: String) {
|
||||
@@ -96,6 +100,7 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
private fun startWebRtc(url: String) {
|
||||
Timber.i("startWebRtc: %s", url)
|
||||
webRtcClient?.release()
|
||||
webRtcClient = WebRtcSenderClient(
|
||||
context = this,
|
||||
@@ -105,6 +110,7 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
private fun stopWebRtc() {
|
||||
Timber.i("stopWebRtc")
|
||||
webRtcClient?.release()
|
||||
webRtcClient = null
|
||||
}
|
||||
@@ -112,5 +118,6 @@ class MainActivity : ComponentActivity() {
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
stopWebRtc()
|
||||
Timber.d("MainActivity onDestroy")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.kimgo.posefit
|
||||
|
||||
import android.app.Application
|
||||
import timber.log.Timber
|
||||
|
||||
class PosefitApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(Timber.DebugTree())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,16 @@ package com.kimgo.posefit.sender
|
||||
|
||||
import org.webrtc.SdpObserver
|
||||
import org.webrtc.SessionDescription
|
||||
import timber.log.Timber
|
||||
|
||||
|
||||
open class SimpleSdpObserver : SdpObserver {
|
||||
override fun onCreateSuccess(desc: SessionDescription) {}
|
||||
override fun onSetSuccess() {}
|
||||
override fun onCreateFailure(error: String) {}
|
||||
override fun onSetFailure(error: String) {}
|
||||
override fun onCreateFailure(error: String) {
|
||||
Timber.e("SDP onCreateFailure: %s", error)
|
||||
}
|
||||
override fun onSetFailure(error: String) {
|
||||
Timber.e("SDP onSetFailure: %s", error)
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import okhttp3.*
|
||||
import org.json.JSONObject
|
||||
import org.webrtc.*
|
||||
import timber.log.Timber
|
||||
|
||||
class WebRtcSenderClient(
|
||||
private val context: Context,
|
||||
@@ -23,6 +24,7 @@ class WebRtcSenderClient(
|
||||
private var surfaceTextureHelper: SurfaceTextureHelper? = null
|
||||
|
||||
fun start() {
|
||||
Timber.i("WebRTC starting, signalingUrl=%s", signalingUrl)
|
||||
initPeerConnectionFactory()
|
||||
connectSignaling()
|
||||
}
|
||||
@@ -47,6 +49,8 @@ class WebRtcSenderClient(
|
||||
.setVideoEncoderFactory(encoderFactory)
|
||||
.setVideoDecoderFactory(decoderFactory)
|
||||
.createPeerConnectionFactory()
|
||||
|
||||
Timber.d("PeerConnectionFactory initialized")
|
||||
}
|
||||
|
||||
private fun connectSignaling() {
|
||||
@@ -57,6 +61,7 @@ class WebRtcSenderClient(
|
||||
webSocket = okHttpClient.newWebSocket(request, object : WebSocketListener() {
|
||||
|
||||
override fun onOpen(webSocket: WebSocket, response: Response) {
|
||||
Timber.d("Signaling WebSocket connected")
|
||||
createPeerConnection()
|
||||
startCamera()
|
||||
createOffer()
|
||||
@@ -65,6 +70,14 @@ class WebRtcSenderClient(
|
||||
override fun onMessage(webSocket: WebSocket, text: String) {
|
||||
handleSignalingMessage(text)
|
||||
}
|
||||
|
||||
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
|
||||
Timber.e(t, "Signaling WebSocket failure")
|
||||
}
|
||||
|
||||
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
|
||||
Timber.w("Signaling WebSocket closed, code=%d, reason=%s", code, reason)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -93,10 +106,16 @@ class WebRtcSenderClient(
|
||||
webSocket.send(json.toString())
|
||||
}
|
||||
|
||||
override fun onIceConnectionChange(state: PeerConnection.IceConnectionState) {
|
||||
Timber.d("ICE connection state: %s", state)
|
||||
}
|
||||
|
||||
override fun onIceGatheringChange(state: PeerConnection.IceGatheringState) {
|
||||
Timber.d("ICE gathering state: %s", state)
|
||||
}
|
||||
|
||||
override fun onSignalingChange(state: PeerConnection.SignalingState) {}
|
||||
override fun onIceConnectionChange(state: PeerConnection.IceConnectionState) {}
|
||||
override fun onIceConnectionReceivingChange(receiving: Boolean) {}
|
||||
override fun onIceGatheringChange(state: PeerConnection.IceGatheringState) {}
|
||||
override fun onIceCandidatesRemoved(candidates: Array<out IceCandidate>) {}
|
||||
override fun onAddStream(stream: MediaStream) {}
|
||||
override fun onRemoveStream(stream: MediaStream) {}
|
||||
@@ -137,6 +156,8 @@ class WebRtcSenderClient(
|
||||
videoTrack,
|
||||
listOf("posefit_stream")
|
||||
)
|
||||
|
||||
Timber.d("Camera started: %s, resolution=1280x720@30fps", cameraName)
|
||||
}
|
||||
|
||||
private fun createOffer() {
|
||||
@@ -160,17 +181,27 @@ class WebRtcSenderClient(
|
||||
}
|
||||
|
||||
webSocket.send(json.toString())
|
||||
Timber.d("Offer sent via signaling")
|
||||
}
|
||||
|
||||
override fun onSetFailure(error: String) {
|
||||
Timber.e("setLocalDescription failed: %s", error)
|
||||
}
|
||||
|
||||
override fun onSetFailure(error: String) {}
|
||||
override fun onCreateSuccess(desc: SessionDescription) {}
|
||||
override fun onCreateFailure(error: String) {}
|
||||
override fun onCreateFailure(error: String) {
|
||||
Timber.e("createOffer failed: %s", error)
|
||||
}
|
||||
}, desc)
|
||||
}
|
||||
|
||||
override fun onSetSuccess() {}
|
||||
override fun onCreateFailure(error: String) {}
|
||||
override fun onSetFailure(error: String) {}
|
||||
override fun onCreateFailure(error: String) {
|
||||
Timber.e("createOffer failed: %s", error)
|
||||
}
|
||||
override fun onSetFailure(error: String) {
|
||||
Timber.e("setLocalDescription failed: %s", error)
|
||||
}
|
||||
|
||||
}, constraints)
|
||||
}
|
||||
@@ -189,6 +220,7 @@ class WebRtcSenderClient(
|
||||
SimpleSdpObserver(),
|
||||
sdp
|
||||
)
|
||||
Timber.d("Answer received from server")
|
||||
}
|
||||
|
||||
"candidate" -> {
|
||||
@@ -204,6 +236,8 @@ class WebRtcSenderClient(
|
||||
}
|
||||
|
||||
fun release() {
|
||||
Timber.i("WebRTC releasing")
|
||||
|
||||
try {
|
||||
videoCapturer?.stopCapture()
|
||||
} catch (_: Exception) {
|
||||
@@ -219,5 +253,7 @@ class WebRtcSenderClient(
|
||||
eglBase.release()
|
||||
webSocket.close(1000, "close")
|
||||
okHttpClient.dispatcher.executorService.shutdown()
|
||||
|
||||
Timber.d("WebRTC released")
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.jetbrains.kotlin.android) apply false
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
org.gradle.java.home=C\:\\Program Files\\Java\\jdk-17
|
||||
android.useAndroidX=true
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. For more details, visit
|
||||
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73bcfb608d1fde9fb62e462f834a3299/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/846ee0d876d26a26f37aa1ce8de73224/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/9482ddec596298c84656d31d16652665/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/39701d92e1756bb2f141eb67cd4c660e/redirect
|
||||
toolchainVersion=21
|
||||
@@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
agp = "9.2.1"
|
||||
agp = "8.7.3"
|
||||
kotlin = "2.0.0"
|
||||
composeBom = "2024.02.00"
|
||||
composeCompiler = "1.5.8"
|
||||
@@ -11,8 +11,10 @@ junitVersion = "1.1.5"
|
||||
espressoCore = "3.5.1"
|
||||
appcompat = "1.6.1"
|
||||
material = "1.10.0"
|
||||
timber = "5.0.1"
|
||||
|
||||
[libraries]
|
||||
timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||
|
||||
+2
-3
@@ -1,9 +1,8 @@
|
||||
#Mon Jun 01 17:35:27 CST 2026
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=2ab2958f2a1e51120c326cad6f385153bb11ee93b3c216c5fccebfdfbb7ec6cb
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
validateDistributionUrl=false
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
Reference in New Issue
Block a user