Skip to content

Repository files navigation

sunnyconf — Android client

Native Android app for sunnyconf: configure a sunnypilot/openpilot device and browse its drives over local WiFi — no internet, no accounts. It discovers the comma via mDNS (_sunnyconf._tcp), fetches /schema + /values from the on-device daemon and renders the settings UI from them, so it hardcodes no parameter list — a new toggle in your fork becomes a new row in the app by itself, no APK update needed.

  • Settings: every sunnypilot settings panel (Toggles, Models, Steering, Cruise, …), rendered from the device's own schema; pairing-code auth; offroad-only settings lock while driving.
  • Drives: route list with the connect-style engagement bar, per-segment video playback, OSM route map, camera switching, clip creation and sharing.
  • Runs everywhere from Android 4.4.2 (API 19) up. The primary target is a GEN5W car head unit (KitKat) — with OEM-look styling on its 1920×720 screen — and the same APK installs on any phone.

Screenshots

Home Drives Drive Models Vehicle
Home Drives Drive Models Vehicle

Install

Grab sunnyconf-vX.Y.Z.apk from Releases and adb install -r it (phones: just open the APK). The device side must be installed first — follow Falseclock/sunnyconf, then set a pairing code on the comma (Settings → Device → Sunnyconf Pairing Code) and enter it in the app when prompted.

Constraints (why it's built this way)

KitKat (API 19) + dual-target forces a deliberately minimal stack:

  • Framework Views only — no AndroidX, no Compose (API 21+). AndroidX + the apksigner META-INF quirk make the APK fail to install on KitKat (INCONSISTENT_CERTIFICATES).
  • java.net.HttpURLConnection + org.json (built in) — no OkHttp/Retrofit. TLS 1.2 is enabled by hand on API 19 (net/Tls12.java) for OSM tile servers.
  • NsdManager for mDNS (API 16+). TXT records need API 21+, so on KitKat the device is identified by service name (e.g. comma3x-1c5bce9a).
  • The one dependency: osmdroid (pure framework Java, Apache-2.0) for the route map.
  • minSdk 19, targetSdk 30 — installs on Android 14+, still runs on KitKat.
  • All sizes/styles live in res/ with three device buckets: values/ (phone portrait), values-land/ (phone landscape), values-w1280dp-long/ (the 1280×420dp head-unit window only).

Build locally

Toolchain: AGP 7.4.2 / Gradle 7.5 / JDK 17 / compileSdk 30 / build-tools 30.0.3 (JDK 21 breaks D8 — see gradle.properties).

bash build.sh        # picks up JAVA_HOME/ANDROID_HOME, falls back to common locations
# → files/sunnyconf.apk (debug-signed)

Or open the project in Android Studio (set Gradle JDK to 17) and Run.

Logs

With the phone (or head unit) on USB and ADB enabled:

adb logcat -d -b crash                          # app crashes (java tracebacks), most recent last
adb logcat -d | grep -i sunnyconf | tail -100   # runtime log lines

When opening an issue, include the crash buffer output, what you tapped, the app version and the Daemon version (both in the status-pill popover), and — for connection problems — whether http://<device-ip>:8765/health opens from the phone's browser. Device-side log collection is described in the daemon README.

Releasing (maintainers)

  1. Bump versionCode and versionName in app/build.gradle.
  2. git tag v<versionName> && git push --tags.
  3. CI (release.yml) builds, signs and attaches the APK to a GitHub Release. Signing material lives in Actions secrets (KEYSTORE_B64, KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD) — the keystore is never committed; keep an offline backup, a lost key means every user has to uninstall/reinstall.

License

MIT — see LICENSE.

About

Native Android client for sunnyconf: configure a sunnypilot device and browse its drives over local WiFi — no internet, no accounts. Android 4.4+ (phones and head units).

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages