Native Android app that wraps the Navi web client in a WebView.
android-client/ — standalone Android project (Kotlin, Gradle).
Single-activity app with two screens:
| Activity | Purpose |
|---|---|
SetupActivity |
First-launch screen — prompts for server URL, saves to SharedPreferences |
MainActivity |
Main screen — full-screen WebView loading the Navi web client |
Server URL is stored in SharedPreferences under key server_url. If absent on launch, SetupActivity is shown. If the WebView fails to load the main frame, the saved URL is cleared so the next launch prompts again.
cd android-client # Debug APK ./gradlew assembleDebug # Install via adb (device connected via USB) adb install -r app/build/outputs/apk/debug/app-debug.apk # One-liner: build + install ./gradlew assembleDebug && adb install -r app/build/outputs/apk/debug/app-debug.apk
| Setting | Value | Reason |
|---|---|---|
javaScriptEnabled |
true | Required for the Vue app |
domStorageEnabled |
true | Session state, composables |
cacheMode |
LOAD_NO_CACHE |
Always fetch fresh from server |
mixedContentMode |
ALWAYS_ALLOW |
Local server may serve mixed content |
userAgentString |
…original… NaviAndroid/1.0 |
Platform detection in web client |
shouldOverrideUrlLoading intercepts navigation:
Intent.ACTION_VIEW in the system browser.Intent.ACTION_VIEW in the system browser:
/content-viewers/.../sessions/{session_id}/files/{filename}download=1This means inline preview cards still render inside the app, but when the user explicitly opens a preview, raw file, download link, or external URL, it leaves the app and opens in the user's browser.
The app appends NaviAndroid/1.0 to the WebView's User-Agent. The web client can detect this:
import { isAndroid } from '@/composables/usePlatform.js'
if (isAndroid) {
// Android-specific behaviour
}
usePlatform.js is a single-line composable:
export const isAndroid = navigator.userAgent.includes('NaviAndroid')
Use this for any future UI differences between the web client and the Android app (hiding elements, adjusting layout, etc.).
Hardware back button navigates WebView history if available (webView.canGoBack()), otherwise falls through to the default Android behaviour (closes the activity).
WebChromeClient.onShowFileChooser is implemented to support image attachment in chat:
CAMERA and READ_MEDIA_IMAGES / READ_EXTERNAL_STORAGE permissions at runtimegetExternalFilesDir(DIRECTORY_PICTURES) via FileProvider