kaa rada na ntsa Β· stay aware on the road
A Kenyan driving-awareness app that speaks up before the camera, the checkpoint or the alcoblow, so you never find out the hard way. π°πͺ
Rada is Swahili for aware. It isn't a radar detector; it's a community of drivers looking out for each other. Rada combines a seeded map of known speed cameras with live reports of police checkpoints and alcohol checks from other drivers, and warns you with a chime and a spoken message in time to react.
The mascot is the Twiga (giraffe): the tallest lookout on the savanna, with a camera lens for an eye. ποΈ
π First run: onboarding and sign-in
![]() Splash |
![]() Cameras, before you reach them |
![]() What's shared, and what isn't |
![]() Alerts, even when Rada is closed |
![]() Create account |
![]() Sign in |
π£οΈ Every day: home, drive, report, help
![]() Home (dark) |
![]() Home (light) |
![]() Drive mode |
![]() One-tap reporting |
![]() Roadside help |
![]() Settings |
![]() Go Pro: pay by card through Google Play |
||
Android, captured on an emulator. Alerts and chart data in these shots are test reports.
| Feature | The details | |
|---|---|---|
| π | Drive mode | A live map that stays locked on your car (a burgundy car marker), your speed, and how many cameras are near. The zoom adapts to your speed and widens to keep an approaching camera on screen. |
| π | Loud, timely alerts | A two-tone chime, then a spoken warning that includes the speed limit for fixed cameras, such as "Speed camera ahead, Thika Road. 300 metres. Limit 80 kilometres per hour.", then a three-beep final warning about 120 m out. Music ducks instead of stopping, and alerts keep working with the screen off or another app open. |
| β±οΈ | Warning distance | Choose how early you're warned: Standard (about 7 s ahead), Early (10 s) or Earliest (14 s), so highway drivers get more time. |
| π | One-tap reporting | Camera, checkpoint or alcohol check, one tap each. The tile floods with colour, you feel a haptic tick, and an Undo chip stays for five seconds so a mis-tap while driving is recoverable. Long-press the app icon for Report camera / checkpoint / alcohol check shortcuts that submit instantly with a spoken confirmation, no screen needed. |
| π | Home dashboard | Estimated fines avoided (cameras you slowed down for, tracked on your account), a weekly line chart of reports by type (amber camera, blue checkpoint, red alcohol), and the newest alerts near you. |
| π | Roadside help | Emergency numbers, tow companies and mechanics, one tap to call. |
| ποΈ | Settings | Your name (from your account) and profile photo, alert switch, an Alert settings sheet (warning distance and a test-sound button), a dark-mode switch and Log out. Everything saves as you change it; there is no Save button. |
| π | Light and dark themes | A lime-on-ink identity with burgundy accents, and an adaptive launcher icon (with a themed variant on Android 13+). |
| π | Rada Pro | Try Drive free for 7 days, then unlock it with a Google Play subscription. See Pricing and payments. |
| π | Android Auto | A car-screen view showing current speed, the active alert and a this-drive evaded/warnings count, sharing live state with the phone's Drive screen. |
flowchart LR
A["π Fused location<br/>lat, lng, speed, bearing"] --> B["π§ SpeedAlertEngine"]
B -->|"in range and heading toward"| C{"Type?"}
C -->|"speed camera"| D["only if you are over the limit"]
C -->|"checkpoint / alcoblow"| E["always"]
D --> F["π AlertSpeaker<br/>chime + voice"]
E --> F
F --> G["π‘ Drive banner<br/>live distance"]
F --> H["π² Notification<br/>if app is in background"]
G --> I["π Final beep at ~120 m"]
- Distance scales with speed. The warning fires about 7 to 14 seconds ahead (your setting), clamped between 60 m and 350 to 700 m.
- Direction matters. Only cameras you're heading toward (within Β±20Β°) count, so the camera on the opposite carriageway stays quiet.
- No repeat spam. Each camera goes
NOT_ALERTED β ALERTED β PASSED, with hysteresis so it doesn't re-fire as you drive by. - Did you slow down? After a warning, the engine tracks the closest approach. If your speed there is at or under the limit (plus 2 km/h for GPS noise), the camera is counted as evaded and the estimated fine is added to your month. If you didn't slow down, only the warning is counted.
- Fast lookups.
CameraGridIndexbuckets cameras into ~1 km cells so each location update only checks the cameras around you. - Runs as a foreground service.
TrackingServiceowns the whole engine β location, alert evaluation, speech, notifications and stats β independently of whatever screen is on top, so Drive keeps watching while you're on WhatsApp, Maps or with the screen off, until you stop it from the persistent notification or sign out.
Note
Camera locations come from public sources and reports. Some are approximate and are flagged
as such in the app. Spots still missing usable coordinates are listed in
docs/cameras-todo.md.
The seeded speed-camera database is Nairobi-focused. Checkpoint and alcohol-check alerts work anywhere, since those come entirely from other drivers' live reports rather than the seeded list.
| Plan | Price | What you get |
|---|---|---|
| π Free trial | 7 days, once per account | Full Drive access |
| π Monthly | KES 200 for 30 days | Keep Drive after the trial, plus alcohol-check alerts |
| π Annual | KES 1,800 for 365 days | Everything in Monthly, about KES 150 a month |
A Google Play subscription, paid by Visa, Mastercard (including M-PESA GlobalPay virtual cards) or M-Pesa where Google offers it at checkout. It auto-renews and is cancelled any time in Google Play.
sequenceDiagram
participant App as π± Rada app
participant F as βοΈ Cloud Functions
participant P as π’ Google Play
participant DB as π₯ Firestore
App->>P: subscribe (card or GlobalPay)
App->>F: verifyPlaySubscription(purchase token)
F->>P: check the purchase
P-->>F: state and expiry
F->>DB: playProUntil, then proUntil
P->>F: renewal / cancel / refund notifications
DB-->>App: proUntil changes, Pro unlocks
A Play purchase is bound to the account that bought it (an obfuscated account id, checked
server-side), and only Cloud Functions can write proUntil β never the client. Details are in
functions/README.md.
Rada Pro is a digital subscription consumed inside the app, which falls under Google Play's Payments policy: real-money purchases of digital content go through Google Play Billing, with narrow exceptions (physical goods/services, or an approved alternative-billing program in specific countries) that don't apply here. Google Play Billing is card-agnostic, so Visa, Mastercard and M-PESA GlobalPay are already covered through it without a second integration.
- π€ Username and password, or Google or Apple. Sign in once and stay signed in.
- β³ The free trial is tied to the account. The start date is stored in Firestore with a server timestamp, so clearing app data or reinstalling doesn't restart it.
- π‘οΈ Firestore rules (
firestore.rules): reports need a signed-in user and can only be deleted by their author; Play purchase records are Cloud-Functions-only, not readable or writable by any client; no client can grant itself Pro or edit its trial. - π Minimal permissions on purpose. No
ACCESS_BACKGROUND_LOCATIONβ Rada only accesses location from a running foreground service, which Android permits on "while in use" permission alone. NoCALL_PHONEβ Roadside help opens the dialer withACTION_DIAL, which needs no permission at all. Noandroid:allowBackupβ auth and account data never leaves the device through a backup.
How usernames work, and console notes
Firebase signs people in with an email address, so a username such as wanjiru is turned into an
internal address, wanjiru@users.rada.invalid, which never receives mail. That makes usernames
unique for free. The trade-off is that there is no password recovery. To add it later, collect a
real email address at sign-up and store it on the account.
- Authentication β Sign-in method: enable Email/Password. That's all username and password needs: no fingerprint, SMS region or Play Integrity.
- Google (optional): enable the Google provider, add your SHA-1 and SHA-256
(
./gradlew :androidApp:signingReport) under Project settings β your Android app, then downloadgoogle-services.jsonagain. - Apple (optional): needs an Apple Developer account: create a Services ID and a Sign in with Apple key, enter them in Firebase, and add Firebase's callback URL to the Services ID.
- Firestore rules: publish
firestore.rules.
| Layer | Choice | Why | |
|---|---|---|---|
| π§ | Shared logic | Kotlin Multiplatform (:shared) |
The alert engine has to be right, so it is written once and reused by both apps instead of being re-implemented per platform. |
| π¨ | Android UI | Jetpack Compose + Material 3 | Declarative UI makes the animated screens (tab bar, report tiles, charts, the moving map) straightforward. |
| π | iOS UI | SwiftUI | Native feel, haptics and animation on iPhone. |
| ποΈ | Architecture | MVI: one immutable state per screen, intents in, effects out | Predictable and easy to reason about. Each feature is a Route (owns the ViewModel) plus a Content screen that is a pure function of state. |
| π§ | Navigation | Navigation Compose, one tab bar above the NavHost |
The active-tab circle slides between destinations instead of being redrawn per screen. |
| πΎ | Local storage | Jetpack DataStore | Small key-value data (theme, name, alert settings, report history), written as it changes. |
| π₯ | Backend | Firebase Auth + Firestore + Cloud Functions | Realtime crowd reports with an offline write queue, and payment logic on a server with no servers to run. |
| π | Location | Play Services Fused Location + a foreground service | One high-accuracy request while Drive is tracking, kept alive in the background. |
| πΊοΈ | Maps | Maps Compose (Google Maps SDK) | Fastest route to a good map with a custom animated car marker. |
| π | Audio | AudioTrack chimes + Android TextToSpeech | No audio assets to ship; navigation-guidance audio focus ducks your music. |
| π | In-car | Android for Cars App Library | A templated car-screen view of Drive state, declared under the IoT category. |
| π | Payments | Google Play Billing | Card-agnostic β covers Visa, Mastercard and M-PESA GlobalPay through one integration. |
| β‘ | Async | Kotlin Coroutines / Flow | Location, Firestore and DataStore are all streams. |
| π οΈ | Build | Gradle Kotlin DSL Β· AGP 8.13 Β· Kotlin 2.3 Β· JDK 17 Β· minSdk 26 Β· targetSdk 36 Β· Node 24 for functions |
shared/ Kotlin Multiplatform: SpeedAlertEngine, CameraGridIndex, models,
LocationProvider / AlertNotifier (expect/actual for Android and iOS)
androidApp/ Jetpack Compose app
β features/ splash Β· onboarding Β· login Β· signup Β· dashboard Β· drive Β· report Β· help Β·
settings Β· paywall (each: State + ViewModel + Route + Content)
β data/ Firestore repositories, DataStore preferences, auth and trial sync
β tracking/ foreground service (owns the Drive engine), alert notifications,
AlertSpeaker (chime + voice)
β car/ Android Auto: CarAppService, Session, Screen, shared car-facing state
β theme/ palette + light/dark colour schemes
functions/ Cloud Functions (Node 24): Google Play subscription verification, notifications, tests
iosApp/ SwiftUI app (see iosApp/SETUP.md)
docs/ screenshots, brand assets, camera data notes
firestore.rules Security rules for reports, Play purchases and accounts
- App shortcuts. Long-press the Rada icon for Report camera, Report checkpoint and Report alcohol check. Each submits instantly with your current location and speaks a short confirmation ("Speed camera reported near Thika Road. Thanks for the heads-up.") with no screen to look at. Falls back to opening the app if you're signed out or haven't granted location. The shortcuts also declare Google Assistant App Action capabilities, so "Hey Google, report a camera on Rada" can be wired up through Play Console's App Actions tool.
- Alerts in the car. The chime and spoken warnings use navigation-guidance audio, the same category Google Maps and Waze use, so they duck your music and play over Bluetooth or Android Auto automatically.
- An Android Auto screen.
RadaCarAppServiceshows current speed, the active alert (with distance and speed limit) and a this-drive evaded/warnings count on the car's display, sharing live state with the phone's Drive screen viaCarDriveState. Declared under the IoT category β the closest fit among Google's fixed Car App Library categories (Navigation, POI, IoT, Weather, Media, Messaging, Calling), since Rada does proximity alerts, not turn-by-turn routing. Sideloaded builds need "Unknown sources" enabled in the Android Auto app's developer settings to show up on a connected head unit before the app is on Play. - CarPlay needs a real iOS app first and an Apple entitlement β not started.
| Area | |
|---|---|
| β | Alert engine, grid index, live map, camera-following, adaptive zoom, audio alerts |
| β | Crowd reports: submit, undo, live alerts, weekly chart |
| β | Fines-avoided tracking, per account and month |
| β | Username/password, Google and Apple sign-in |
| β | Free trial tied to the account |
| β | Firestore security rules |
| π§ͺ | Google Play subscriptions β needs Play Console setup (products, API access) |
| π§ | iOS app β a SwiftUI prototype with mock data; no location, map or sign-in yet |
| π | Password recovery |
| π | Renewal reminders |
| π | Offline maps |
| π | Remaining camera coordinates β see docs/cameras-todo.md |
Important
The tow and mechanic phone numbers are placeholders, and the iOS prototype uses mock data for its Home card.
Private project. No licence is granted. π
Made in Nairobi π°πͺ Β· kaa rada na ntsa












