# skatespots-background A **local Capacitor Android plugin** that gives the APK closed-app notifications **without Google services** — the [Cordn](https://github.com/Cordn-msg/cordn-web) pattern, simplified (our payloads are already content-free, so there is **no Rust and no decryption** here). It polls our own `push-service` (`GET /pending?token&since` → `{seq, at, changed}`) and, when the cursor advances, raises a **local notification**. ## Modes | Mode | Mechanism | Cadence | Notes | | --- | --- | --- | --- | | `off` | — | — | default | | `standard` | **WorkManager** | ~15 min (OS minimum) | best-effort — Doze/OEM battery managers may defer it | | `fast` | **foreground service** | ~5 min | near-live; shows a **sticky notification** + battery | ## Files - `src/index.ts` — TS↔Kotlin bridge (the app registers the plugin **by name**). - `android/src/main/AndroidManifest.xml` — permissions (`POST_NOTIFICATIONS`, `FOREGROUND_SERVICE[_DATA_SYNC]`, `WAKE_LOCK`, `RECEIVE_BOOT_COMPLETED`, `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS`) + the service. - `android/src/main/java/org/skatespots/background/`: - `SkateSpotsBackgroundPlugin.kt` — the `@CapacitorPlugin` (`configure`, `seed`, `postNotification`, `clearNotifications`, `consumePendingUrl`, `isBatteryExempted`, `requestBatteryExemption`). - `PollWorker.kt` (WorkManager), `PollService.kt` (foreground), `Poller.kt`, `Notifier.kt`, `PollPrefs.kt`. - `android/build.gradle` — the plugin Gradle module. ## Wiring 1. The root `package.json` depends on it: `"skatespots-background": "file:packages/skatespots-background"`. 2. `npm run android:init` / `android:sync` (which run `npx cap sync android`) pick it up and add the Android module. 3. The client enables it from **Settings → Notifications → Background delivery (Android)** via `src/hooks/useBackgroundDelivery.ts`. ## ⚠️ Caveats - **Android-only** and **cannot be verified in CI** — needs a device. - `standard` is **not** a guarantee (Doze/OEM). `fast` needs the sticky notification and the user must start it while the app is foreground. - `build.gradle` mirrors the Capacitor plugin template; align its Gradle/Kotlin versions with the app's Capacitor major if a build complains. - The small icon uses `applicationInfo.icon`; swap for a dedicated monochrome status icon if the app's launcher icon renders poorly in the shade. ## Server contract `push-service` (see its README): `POST /native/poll/register` (NIP-98 proof → poll token), `GET /pending?token&since`, `POST /native/poll/unregister`.