A TeamSpeak 3 client for Android built with Flutter & Rust
- Voice chat — real-time OpusVoice (48kHz mono) with VAD and PTT
- Full mute — one-tap headset button (or the media card play/pause) silences input + output and stops the mic
- Background keep-alive — stays connected in the background like a music player, backed by a foreground service + media session with mute/disconnect notification controls
- Per-client volume — adjust each user's volume locally, remembered by identity across sessions
- Channel chat — send and receive text messages in channels
- Server bookmarks — save and manage server addresses locally
- First-use guide — interactive spotlight coach marks on the real UI (re-viewable from the help icons)
- Voice settings — VAD / PTT / mic gain / threshold tuning from the settings screen, by long-pressing the mic button, or by tapping your own name in the user list, with a live mic level + mic test
- OTA updates — checks GitHub/Gitee releases (tag format
vx.y.z) on launch, downloads the ABI-matched APK and installs it; check can be disabled and the source chosen in settings
| Layer | Stack |
|---|---|
| UI | Flutter (Dart) + Riverpod |
| Protocol & codec | Rust (tsclientlib, opus-rs) |
| Playback | Rust (cpal — continuous output stream, silence when idle) |
| Mic capture | Kotlin (AudioRecord) → EventChannel → Dart → FFI → Rust |
| Background persistence | KeepAliveService (foreground service + MediaSession) |
Flutter (Dart) Rust (Native .so)
───────────── ─────────────────
lib/services/ts_ffi.dart ←FFI→ native/src/api.rs
lib/services/audio_service.dart native/src/lib.rs
lib/models/ts_state.dart (tsclientlib + opus-rs + tokio)
Kotlin (Android)
────────────────
MainActivity.kt ←EventChannel→ audio_service.dart (mic via AudioRecord)
KeepAliveService.kt ←MethodChannel→ foreground_service.dart (foreground service
+ MediaSession + notification controls)
| Tool | Version |
|---|---|
| Flutter | 3.x (Dart >=3.11) |
| Rust | 1.70+ |
| Android SDK | Latest |
| Android NDK | 26+ |
Quick way — builds both ABIs and copies the .so files in one step:
# 1. Install Rust Android targets
rustup target add aarch64-linux-android x86_64-linux-android
# 2. Build the native library (requires ANDROID_NDK_HOME pointing at an installed NDK)
python3 pre_build.py
# 3. Run
flutter runManual alternative (same result, step by step):
cd native
cargo build --release --target aarch64-linux-android
cargo build --release --target x86_64-linux-android
cp target/aarch64-linux-android/release/libtsclient.so ../android/app/src/main/jniLibs/arm64-v8a/
cp target/x86_64-linux-android/release/libtsclient.so ../android/app/src/main/jniLibs/x86_64/libtsclient.so is gitignored — the app runs only after it has been built and copied.
adb logcat | grep flutter # Flutter logs
adb logcat | grep RustStdouterr # Rust logs
adb logcat | grep -E "cpal|opus" # Audio logs
adb shell dumpsys media_session # Media session active/playing (keep-alive)
adb shell dumpsys activity services com.senlinjun.nek0 # Foreground service state| Permission | Purpose |
|---|---|
INTERNET |
Connect to TeamSpeak servers |
RECORD_AUDIO |
Microphone capture (requested at runtime) |
FOREGROUND_SERVICE / FOREGROUND_SERVICE_MEDIA_PLAYBACK / FOREGROUND_SERVICE_MICROPHONE |
Background keep-alive service |
POST_NOTIFICATIONS |
Service notification (Android 13+) |
WAKE_LOCK |
Keep the CPU awake for audio while connected |
REQUEST_INSTALL_PACKAGES |
OTA update APK installation |
WRITE_EXTERNAL_STORAGE |
OTA download (API <= 28) |
Nek0/
├── android/app/src/main/
│ ├── jniLibs/ # Pre-built .so files (gitignored, built by pre_build.py)
│ ├── kotlin/.../MainActivity.kt # Mic capture (AudioRecord), platform channels
│ ├── kotlin/.../KeepAliveService.kt # Foreground service + MediaSession
│ ├── kotlin/.../NotificationActionReceiver.kt # Notification button actions
│ ├── res/xml/filepaths.xml # OTA update file provider paths
│ └── AndroidManifest.xml
├── lib/ # Flutter
│ ├── models/ # Data models + Riverpod state
│ ├── screens/ # Home / server / settings screens
│ ├── services/ # FFI bindings, audio, foreground service, OTA
│ └── widgets/ # UI components (spotlight tour, voice panel, ...)
├── native/ # Rust
│ ├── Cargo.toml # Patches tsclientlib/tsproto → local_tsclientlib/
│ ├── local_tsclientlib/ # Vendored tsclientlib/tsproto sources
│ └── src/
│ ├── lib.rs # State, types, command queue
│ └── api.rs # FFI functions, event loop, audio codec
├── resource/
│ └── logo.png
├── AGENTS.md # Architecture & build guide for AI agents
├── README.md
├── README_ZH.md
├── CONTRIBUTING.md
└── pubspec.yaml
See CONTRIBUTING.md.
For educational use. tsclientlib has its own license.
