Document the Android app build and the state of the plan

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AuthorKonata <konata@posteo.jp>
Date
Commit67e3a3362f8a2e2aff9c5f1cc82b45b84940615c
Parent9d2b928
2 files changed, 21 insertions(+), 5 deletions(-)
▾MREADME.md
@@ -7,6 +7,7 @@ crates/api JSON types shared by server, CLI and web
crates/server otserver: axum + SQLite, serves the API and web/dist
crates/cli ot: test client (register a device, send points, simulate a walk)
web/ Leptos + Leaflet, built with Trunk
android/ Android app: background tracking, this device's map, see docs/android.md
```
## Development
@@ -20,6 +21,18 @@ cargo run -p cli -- simulate --interval 2 --batch 5 48.137 11.575
cargo run -p cli -- people
```
### Android app
Needs JDK 17 or newer and the Android SDK in `ANDROID_HOME`:
```sh
cd android
ANDROID_HOME=~/android-sdk ./gradlew testDebugUnitTest assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
Debug builds allow plain HTTP. In the emulator, the server on the host is `http://10.0.2.2:8080`. `adb emu geo fix <lon> <lat>` moves the emulator's GPS.
## Configuration
Every flag can also be set by its environment variable. `otserver --help` lists them.
▾Mdocs/android.md
@@ -34,8 +34,9 @@ TrackerService (foreground service, type location)
BootReceiver: starts TrackerService after a reboot, if tracking was on
```
- **Language and build:** Kotlin, Gradle, minSdk 29, targetSdk current.
- **Dependencies:** OkHttp and AndroidX Browser (for Custom Tabs). Jetpack Compose only if the top bar needs more than plain views.
- **App ID:** `org.opentracker`, and `org.opentracker.debug` for debug builds.
- **Language and build:** Kotlin, Gradle, minSdk 31 (Android 12, for GNSS batching and the modern `LocationRequest`), targetSdk 36.
- **Dependencies:** only AndroidX Browser, for Custom Tabs. HTTP uses `HttpURLConnection`, JSON uses the platform's `org.json`, and the UI uses plain platform views.
- **No Google Play Services.** The app must work on de-Googled phones. The fused location provider and activity recognition need Play Services, so the app uses `LocationManager` and sensors.
## Connecting the app to an account
@@ -110,11 +111,11 @@ The policy is pure Kotlin with no Android types. It gets the time as a parameter
### GNSS batching
On Android 12 and newer, `LocationRequest.Builder.setMaxUpdateDelayMillis` lets the GNSS chip collect fixes while the CPU sleeps. It then delivers them in one batch.
`LocationRequest.Builder.setMaxUpdateDelayMillis` lets the GNSS chip collect fixes while the CPU sleeps. It then delivers them in one batch.
- Walk mode uses a 2-minute delay and Vehicle mode 1 minute.
- The map then lags behind by that delay, which is fine for this app.
- On Android 10 and 11 the app gets fixes one by one.
- **Fallback:** some GNSS chips accept a batching request and then deliver almost nothing. The emulator does this. If no fix arrives within two batch periods, the service turns batching off until it restarts. Indoors, GNSS is silent anyway, so the fallback may also trigger there. That only costs some battery.
### Uploads
@@ -180,8 +181,10 @@ The permission flow asks in steps: fine location, then "Allow all the time" in s
## Steps
Steps 1 to 6 are done and tested in the emulator. Doze and the watchdog are not tested yet, because they need hours on a real phone.
1. **Server:** device endpoints, pairing endpoints, `#device` and `#pair` web modes. Tests for pairing and device-only access.
2. **App skeleton:** MainActivity with the WebView in device mode, token in encrypted preferences, manual token paste.
2. **App skeleton:** MainActivity with the WebView in device mode, token in app-private preferences, manual token paste. Backups and device transfers exclude all app data, so the token never leaves the phone.
3. **Tracking v1:** foreground service, `LocationManager`, fixed 30 s interval, outbox, uploader, notification.
4. **Battery:** sampling policy with JVM tests, motion detector, GNSS batching, upload batching, watchdog, boot receiver.
5. **Pairing:** Custom Tab flow and the code exchange.