packages/skatespots-background: a local Capacitor Android plugin that polls our own push-service /pending and raises local notifications. Modes: off / standard (WorkManager ~15 min) / fast (foreground service ~5 min). Kotlin + AndroidManifest (POST_NOTIFICATIONS, FOREGROUND_SERVICE_DATA_SYNC, WAKE_LOCK, battery-exemption) + Gradle module. Client: useBackgroundDelivery (registers a poll token via NIP-98, seeds the plugin) + a Background delivery (Android) control in NotificationSettingsCard. The app registers by NAME, not by importing the package, so the web bundle is unaffected. UNVERIFIED - needs cap sync + a device.
2.5 KiB
2.5 KiB
skatespots-background
A local Capacitor Android plugin that gives the APK closed-app notifications without Google services — the Cordn 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
- The root
package.jsondepends on it:"skatespots-background": "file:packages/skatespots-background". npm run android:init/android:sync(which runnpx cap sync android) pick it up and add the Android module.- 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.
standardis not a guarantee (Doze/OEM).fastneeds the sticky notification and the user must start it while the app is foreground.build.gradlemirrors 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.