Work / Mobile
FitFindr
Android app that names your outfit from one photo, wired to a 4B vision-language model built to run on the phone’s NPU.
- Kotlin
- Android (AGP 8.6, minSdk 27, targetSdk 35)
- Nexa AI SDK
- OmniNeural-4B
- Kotlin coroutines
- OkHttp
- Google Stitch (design)
TL;DR
- FitFindr answers “What am I wearing?” from a single photo, with the model on the phone instead of in the cloud.
- It’s wired to OmniNeural-4B, a 4-billion-parameter vision-language model, through the Nexa AI SDK’s plugin for Snapdragon’s Hexagon NPU.
- The debug build compiled to a 111 MB APK. Proving real output on a Snapdragon device is next.
What it does
Photos come from the gallery or the camera (through a FileProvider) and are copied into cache. On tap, inference runs off the main thread in a coroutine. The prompt asks for each clothing item with its colour and style, and the app is built to stream the answer token by token into a result card.
A 4B model doesn’t belong in an APK, so an in-app downloader pulls the model’s 14 files from Hugging Face with OkHttp and shows per-file progress before the first run.
The hard part
Shipping against a binary SDK you can’t compile against. The Nexa SDK’s classes weren’t visible to Kotlin at compile time. Rather than stall on the build, every SDK call resolves by name at runtime: constructing the vision-language wrapper on the NPU plugin, applying the chat template to an image-plus-text message, and pulling the token stream.
Reflection → it unblocks on-device inference without waiting on the SDK’s Kotlin surface → no compile-time type safety, so an SDK update fails at runtime instead of at build time. All of it lives in one file, so the rest of the app stays typed and the risk stays in one place.
Next
This is the first screen of a bigger product: scan, then wardrobe, then build an outfit, then share. With an AI assistant I mapped the rest into a page-by-page vision doc, and I generated five Google Stitch mockups. The immediate next step is a verified on-device run.
Verified numbers
| Metric | Value | Source |
|---|---|---|
| Debug APK | 111 MB | local: FitFindr/app/build/outputs/apk/debug/app-debug.apk |
| Model files fetched in-app | 14 | local: FitFindr/app/src/main/java/com/fitfindr/app/ModelDownloader.kt |
| Max streamed tokens per answer | 512 | local: FitFindr/app/src/main/java/com/fitfindr/app/NexaSdkReflection.kt |