Spoof your GPS location on Android. Point your phone anywhere on the map using a floating joystick, saved routes, or automatic roaming while your other apps keep running normally.
- Free and open-source — no subscriptions, no premium tiers, no paywalled features, no ads
- No root required — works out of the box via Android's built-in Developer Options mock location setting
- Runs in the background — joystick, widget, and routes all stay active while other apps run in the foreground
- Import in seconds — bring your saved routes from GPS Joystick or YAMLA without starting from scratch
Here's everything included:
| Feature | Description |
|---|---|
| Map | OpenStreetMap via MapLibre (GPU-accelerated, offline-capable). Tap to walk or teleport. Spoofed position shown as live marker. |
| Last Position | Restores last spoofed location on app restart. No manual re-entry needed. |
| Joystick | Floating overlay stays on top of any app. Drag to move in any direction at chosen speed. Draggable anywhere on screen. |
| Speed Profiles | Walk / Run / Bike presets, all user-editable. Anti-cheat warning when speed exceeds threshold. Accessible from floating widget. |
| Routes | Create waypoints on map → polyline. Two types: straight (direct segments) and guided (OSRM road-following). Save, edit, replay, loop, or record in real time. Import from GPX files. |
| Roaming | Set center, radius, duration. Auto-walks randomly within radius. Optional road-following via OSRM. Optional return-to-start after loop completes. Configured via bottom sheet on Map screen. |
| Favorites | Save named map positions. Instantly teleport or walk to any. Add via inline dialog or MapPicker with Nominatim search. Optional curated list of 26 popular locations (Settings → Favorites → Show hot locations). |
| Floating Widget | Configurable quick-access panel floats over other apps. Collapsible FAB → expanded panel with user-selected controls. |
| Click-to-Move | Long-press map → "Walk here" or "Teleport here". Walk advances at current speed; teleport jumps instantly. |
| QR Transfer | Share or import config between devices via QR codes. Export splits into scannable chunks; import scans and reassembles. |
| GPS Realism | Makes spoofed GPS indistinguishable from a real chip. Toggle per-feature: bearing hold when stationary, realistic altitude drift, warm-up accuracy envelope (converges over 30 s), satellite count in fix (7–14), and natural signal dropouts (auto-paused during route replay and walk-to). All off by default; enable selectively in Settings. |
| Import/Export | All data to/from JSON (routes, favorites, speed profiles, widget config, roaming defaults, jitter settings). Route import also supports GPX, GPS Joystick, and YAMLA formats. |
| Background Service | Spoofs while minimized or screen off via foreground service. Low-priority notification. |
| Onboarding | Multi-step first-run flow: location permission, overlay permission, mock location enablement. |
| Elevation Controls | (Experimental, root required) Injects synthetic accelerometer + rotation-vector sensor events so apps see the phone as tilted. Three modes: tilt up / neutral / tilt down. Controlled from the floating widget. Disabled automatically for non-root devices. |
| About | App version, GitHub, privacy policy, and open-source credits. Accessible from home screen and navigation drawer. |
Pre-built APKs on Releases page.
Sideload:
adb install locationjoystick-vX.X.X.apkOr transfer APK to device and open with file manager (allow installs from unknown sources).
Settings → About phone → tap Build number seven times → Developer Options unlocked.
Settings → System → Developer Options → Select mock location app → choose locationjoystick.
Open locationjoystick → tap Grant Permission → find locationjoystick in list → enable toggle → return to app.
Open locationjoystick → tap map to teleport or use joystick → open target app → locationjoystick keeps running in background.
Note: Some apps detect mock locations. Check the app's community for current workarounds. Root is not required for any core feature — the Elevation Controls widget (experimental) is the only feature that optionally uses root, and it can be ignored entirely.
Coverage tracked via kotlinx-kover. Aggregates all modules into a single report.
./gradlew koverHtmlReport # HTML report → build/reports/kover/html/index.html
./gradlew koverXmlReport # XML report for CI → build/reports/kover/report.xmlOr via Make:
make test # unit tests (JVM)
make smoke-test # end-to-end navigation suite (requires connected device/emulator)
make coverage # generate both reports
make coverage-open # open HTML in browser- Android Studio Hedgehog or newer (or JDK + Android SDK command-line tools)
- Java 17
- Android SDK with API 31+
git clone https://github.com/shortcuts/locationjoystick.git
cd locationjoystick
./gradlew assembleDebugDebug APK at app/build/outputs/apk/debug/app-debug.apk.
adb install app/build/outputs/apk/debug/app-debug.apk./gradlew assembleReleaseTo build a release AAB for manual Play Store upload:
make bundleAAB at app/build/outputs/bundle/release/app-release.aab.
git tag v1.0.0
git push origin v1.0.0GitHub Actions builds, signs, uploads APK to GitHub Releases on tag push.
Multi-module NowInAndroid-style. Each feature = Gradle module. Shared code in :core:*.
feature/* — UI + ViewModels (Compose screens, no business logic)
↓ depends on
core/data — Repositories (single source of truth)
↓
core/database — Room DB
core/datastore — DataStore Prefs
core/location — Mock GPS engine (ForegroundService), independent of UI
core/model — Pure Kotlin data classes, no Android deps
MVVM + Repository. ViewModels expose StateFlow/SharedFlow. Compose collects via collectAsStateWithLifecycle(). Hilt DI throughout. LjApp wraps LjNavHost in a ModalNavigationDrawer. IdleScreen serves as the main hub after onboarding, with cards navigating to Map, Routes, Favorites, and Settings.
Each feature split into :api (public contract) + :impl (implementation).
| Module | Purpose |
|---|---|
:app |
Entry point, Hilt setup, LjApp composable, LjNavHost, drawer |
:core:common |
Utilities, extensions, constants (AppConstants) |
:core:data |
Repositories, DataStore preferences |
:core:database |
Room DB (v2), DAOs, entities |
:core:datastore |
DataStore preferences source |
:core:designsystem |
Design tokens, theme, typography, shared components |
:core:location |
Mock GPS foreground service + movement engine |
:core:model |
Pure Kotlin domain data classes |
:core:map |
GeoJSON utils, MapLibre lifecycle bridge, style extensions |
:core:overlay |
Shared WindowManager overlay utilities |
:core:routing |
OSRM client, route interpolation, roaming engine, replay engine |
:core:testing |
Shared test utilities, fakes |
:feature:favorites:api / :impl |
Favorites list, MapPicker, teleport |
:feature:joystick:api / :impl |
Floating joystick overlay service |
:feature:map:api / :impl |
MapLibre screen, map interactions, roaming bottom sheet |
:feature:onboarding:api / :impl |
Multi-step onboarding flow |
:feature:routes:api / :impl |
Route list, creator, detail, replay |
:feature:settings:api / :impl |
Speed profiles, widget config, export/import, QR transfer |
:feature:widget:api / :impl |
Floating widget overlay service, map floating view |
| Component | Library |
|---|---|
| Language | Kotlin 2.x |
| UI | Jetpack Compose + Material3 |
| Map | MapLibre Android SDK 12.x |
| DI | Hilt (Dagger) |
| Database | Room |
| Preferences | DataStore (Preferences) |
| Routing | OSRM (router.project-osrm.org) |
| Serialization | kotlinx-serialization (JSON) |
| Async | Kotlin Coroutines + Flow |
| Build | Gradle + Version Catalog (libs.versions.toml) |
| CI | GitHub Actions |
| Min SDK | API 31 (Android 12) |
See CONTRIBUTING.md for PR rules, required checks, and reference docs.
MIT License. See LICENSE for full text.