Add the Android app: Gradle build, Oboe audio, connection screen

android/ builds core and ts3j from the same sources as the desktop's
Maven build, so the app shares all of the client's logic:

- audio: Oboe streams behind AudioCapture/AudioPlayback, with a lock-free
  ring between the real-time callback and the blocking Java side, and
  libopus 1.5.2 built with the NDK behind OpusCodec. Speakers are mixed
  onto one stream. Capture uses the VoiceRecognition preset, leaving
  noise suppression and gain to the client's own processing.
- app: a plain connection screen to try the port out - connect,
  microphone, mute, deafen, channel chat and a log - until the real UI.

Targets Android 13 and up (minSdk 33) on arm64 and x86_64.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 08:24:21 +00:00
parent e211ffa7b6
commit 086b913c8e
26 changed files with 1555 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
[versions]
agp = "9.4.1"
kotlin = "2.4.20"
composeBom = "2026.09.00"
activityCompose = "1.13.0"
lifecycle = "2.11.0"
bouncycastle = "1.86"
ini4j = "0.5.1"
oboe = "1.11.0"
[libraries]
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
androidx-compose-material3 = { module = "androidx.compose.material3:material3" }
androidx-compose-ui = { module = "androidx.compose.ui:ui" }
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" }
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
bouncycastle = { module = "org.bouncycastle:bcprov-jdk18on", version.ref = "bouncycastle" }
ini4j = { module = "org.ini4j:ini4j", version.ref = "ini4j" }
oboe = { module = "com.google.oboe:oboe", version.ref = "oboe" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

Binary file not shown.

View File

@@ -0,0 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.0-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists