# Android companion

The Android app is a focused native companion rather than a copy of the web dashboard. It connects directly to the Pi's BLE GATT service and provides:

- live Pi health, temperature, memory, storage, and ADB connection status;
- live car speed, gear, steering, battery, range, and lifetime statistics;
- launch access to ADB shortcuts that were explicitly saved in the web dashboard;
- phone GPS, speed, bearing, accuracy, battery, and network-state uplink;
- background BLE reconnection and location updates through a foreground service.

## Pairing

1. Deploy the latest Pi release with `./install.sh` so BlueZ and the Bluetooth bridge are installed.
2. Open **Settings → Mobile** in the web dashboard and select **Pair a phone**.
3. If needed, turn Bluetooth on and select **Make discoverable**. The Pi remains discoverable for three minutes.
4. Install and open the Android application and grant Bluetooth, notification, and precise-location permissions.
5. Enter the six-digit code shown by the dashboard.

The one-use code expires after ten minutes. The resulting credential is encrypted with Android Keystore and can be revoked from **Settings → Mobile**. A phone can only launch existing allowlisted ADB shortcuts; the Bluetooth protocol has no shell, arbitrary ADB, APK upload, update, or power operation.

## Build

Open this `android/` directory in Android Studio (JDK 17, Android SDK 35) and run the `app` configuration, or build the downloadable APK from the repository root:

```bash
./build-apk.sh
```

The debug APK is copied to [`apks/pi-car-companion-debug.apk`](../apks/pi-car-companion-debug.apk). Hardware validation requires an Android 8+ phone with BLE and a Raspberry Pi with a BlueZ-compatible BLE adapter.

## BLE protocol

The custom service UUID is `6c7a0001-7c6d-4f74-9bb0-c5a4e5efc001`. RX and TX carry newline-delimited UTF-8 JSON, fragmented into BLE-sized chunks. Protocol version 1 exposes only `pair`, `snapshot`, `location`, and `launchShortcut` operations. Android sends GPS at most every second and refreshes the dashboard snapshot every five seconds.
