集成 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:
2026-06-01 23:50:57 +08:00
parent 334df75155
commit a355919cdc
11 changed files with 81 additions and 25 deletions
+2
View File
@@ -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"
}
+1
View File
@@ -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")
}
}