Turn-by-turn Google Maps directions on your Pebble. Start navigation in Google Maps on your Android phone and the next turn — arrow, distance, and street — pops up on the watch automatically. Built for the relaunched, open-source Pebble (primary target Pebble Time 2, works across Pebble platforms).
I wanted a simple & open-source turn-direction (and eventually map) app for pebble. This is not fancy, but you can evaluate how it works (for security.) I tested on latest Graphene on a Pixel 10 Pro.
It requires a companion-app, and for you to get Google Map directions, first. If you want something standalone, check out Navi App which is excellant.
Two parts: the watchapp (on the watch) and the Android companion (on the phone).
Watchapp — install Maps Nav from the RePebble appstore (or
open the .pbw from a release in
the Pebble app).
Android companion — no Google Play needed:
- Obtainium (easiest, auto-updates): install
Obtainium, then Add App with this URL:
https://github.com/konsumer/pebble-map-android. It installs the latest signed APK and keeps it updated. - Manual: download
pebble-maps-nav.apkfrom the latest release.
Then grant notification access (see Permissions) and start driving directions in Google Maps.
I wanted this to be very source-tracable, so you can see exactly how the file was built in Github CI. This allows you to verify I didn't do something sneaky, but also not require you to build it yourself. The exact process used to build them is here
- Click on latest green action-run here
- scroll to bottom (after inspecting run, etc) and download
app-debug-apkandwatchapp-pbwto your phone. they are zips, so extract them in your file-browser. Install the APK, and open the pbw in Pebble.
You can also find the APK on any release for easier download.
On Graphene/Android, permissions are tricky for self-installed APKs. I did this:
- Settings → Apps → Pebble Maps Nav (the app's info page).
- Tap the ⋮ three‑dot menu in the top‑right corner.
- Tap "Allow restricted settings."
- Go back to "notifications read, reply & control" → now the toggle for Pebble Maps Nav will enable. Confirm the warning dialog.
At some point, I may publish to play-store, but for now, this is basically just for me & my friends that have Pebbles.
Google has no public live-navigation API — the Directions API only returns a static route, not the GPS-synced "in 200 m, turn left" stream. The only way to mirror live Google Maps guidance is to read the navigation notification Maps posts while navigating. So:
Google Maps (phone)
│ posts ongoing navigation notification (custom RemoteViews)
▼
NotificationListenerService ──► parse turn / distance / street / ETA + maneuver icon
│
▼
PebbleKit Android 2 ──► launches the watchapp + sends an AppMessage each update
▼
Watchapp (C) ──► one screen: arrow, distance, street, trip summary
The maneuver arrow is the actual icon Google draws (downsampled and forwarded), so it stays correct regardless of language or new maneuver types. The text (distance/street/ETA) is parsed best-effort; if a field is ever missed, the arrow still shows.
| Path | What |
|---|---|
shared-contract.md |
UUID, AppMessage keys, maneuver enum, arrow packing — read first |
watchapp/ |
Pebble watchapp in C (adaptive across aplite/basalt/chalk/diorite/emery) |
android/ |
Android companion (Kotlin) |
The watchapp builds with the modern Rebble toolchain (the original SDK was Python 2).
Option A — rebbletool (local SDK):
pip install rebbletool # provides the `pebble` command on Python 3
cd watchapp
pebble build
pebble install --phone <PHONE_IP> # or sideload the .pbw via the new Pebble appOption B — Docker:
cd watchapp
docker run --rm -v "$PWD":/app rebble/pebble-sdk pebble buildThe build produces watchapp/build/pebble-gmaps-nav.pbw. Install it on the watch with the
new Pebble mobile app (Settings → sideload / "Install app from file").
Requires Android Studio or a local Gradle + Android SDK. PebbleKit Android 2 is pulled from
Maven Central (io.rebble.pebblekit2:client).
cd android
# If you don't have the gradle wrapper jar, generate it once: `gradle wrapper`
./gradlew assembleDebug # build the APK
./gradlew test # run NavParser unit tests
adb install app/build/outputs/apk/debug/app-debug.apkThen on the phone:
- Open Pebble Maps Nav.
- Tap Grant Notification Access and enable the app (this lets it read the Maps navigation notification).
- Tap Test send to watch to confirm the watch link works.
- Start driving directions in Google Maps — the watchapp launches and updates itself.
A single screen shows everything that's available at once: the maneuver arrow, distance to the turn, the street, and a trip-summary line (time left · distance left · ETA). Press Back to exit.
cd android && ./gradlew test— parser tests over real-notification text fixtures.- Watchapp compiles clean for every target platform (
pebble build). - Test send button exercises phone→watch delivery and all three views without driving.
- On-device: start Google Maps navigation → watch shows and updates each turn; ending navigation returns the watch to its watchface.
Continuous integration: .github/workflows/ci.yml builds both halves on every push/PR —
the Android job runs assembleDebug + test (and uploads the debug APK), and the watchapp
job runs pebble build inside the rebble/pebble-sdk Docker image. The badge above is your
green/red signal.
- iOS is not supported for this feature. iOS sandboxes notifications, so no app can read Google Maps' navigation notification. There is no equivalent path; this is Android-only by platform design, not by choice.
- Notification scraping is inherently fragile. If Google changes the navigation
notification layout, text parsing may need updating (resource names live in
GMapsNotificationReader.kt). The arrow icon is the most robust signal and is forwarded directly. - The "map" screen is a textual overview, not real map tiles. The notification carries no route geometry to draw, and a real static-map render would need an API key and your live location, which we don't have.
- Keep the watchapp UUID and the AppMessage key numbers in sync across
watchapp/src/c/keys.h,watchapp/package.json, andPebbleForwarder.kt— seeshared-contract.md.
# generate a key
docker run --rm -it --user "$(id -u):$(id -g)" -v "$PWD":/work -w /work \
eclipse-temurin:17-jdk \
keytool -genkeypair -v -keystore pebble-maps-nav.keystore \
-alias pebble-maps-nav -keyalg RSA -keysize 2048 -validity 10000
base64 -w0 pebble-maps-nav.keystore
GitHub repo → Settings → Secrets and variables → Actions → New repository secret:
- KEYSTORE_BASE64 → from last step
- KEYSTORE_PASSWORD → your keystore password
- KEY_ALIAS → pebble-maps-nav
- KEY_PASSWORD → your key password (same as keystore if you reused it)
- Google Maps notification parsing approach and resource names are modelled on 3v1n0/GMapsParser (LGPL-3.0).
- PebbleKit Android 2 for phone↔watch communication, and the Rebble project for the open-source Pebble SDK.