"I was going to convert this to a beautiful KMM desktop app, but then I realized I'd rather ship working software than spend 3 months building a GUI nobody asked for. Also, my cat keeps sitting on my keyboard when I try to write Compose code." ๐ธ
A production-grade GPS simulator that makes your Android emulator think it's taking a scenic route through your GPX/KML files. Think of it as a teleportation device for your test devices, minus the existential dread.
Perfect for testing location-based apps without having to:
- Actually walk/drive around like some kind of analog peasant ๐ถโโ๏ธ
- Manually click "set location" 847 times in the emulator
- Explain to your neighbors why you're walking in circles around the block with your laptop
- Multi-format support: GPX, KML, and "whatever weird format your GPS watch exports"
- Realistic speed presets: From walking (for fitness apps) to highway (for "oh crap the demo is in 5 minutes")
- Smart parsing: Handles trackpoints, waypoints, and route points because GPS file formats are apparently suggestions
- Multi-emulator support: Send the same route to all your emulators simultaneously (chaos mode engaged)
- Bearing simulation: Your navigation app will know which way you're "heading"
- Loop mode: For when you want to test that jogging route... forever ๐
- Professional logging: Because debugging GPS issues at 2 AM is enough suffering
- Bash 3.x compatibility: Yes, even your ancient macOS bash will work (you're welcome, time travelers)
# macOS (if you're into that sort of thing)
brew install android-platform-tools xmlstarlet bc
# Ubuntu/Debian (for the cultured developer)
sudo apt-get install android-tools-adb xmlstarlet bc
# Arch Linux (BTW I use Arch)
sudo pacman -S android-tools xmlstarlet bc# 1. Make it executable (as all good scripts should be)
chmod +x routing.sh
# 2. Install convenient aliases (because typing is hard)
./routing.sh --install-aliases
# 3. Reload your shell (or just restart terminal like a normal person)
source ~/.bashrc # or ~/.zshrc if you're fancy# Test a route (see what happens without commitment issues)
gps-test route.gpx
# Simulate walking (perfect for fitness apps or existential contemplation)
gps-walk route.gpx
# Simulate driving (for when you need to test ride-sharing apps from your couch)
gps-drive route.gpx
# Debug mode (fast and chatty, like me after coffee)
gps-debug route.gpx# Continuous testing (because some bugs only appear on the 47th loop)
gps-walk --loop route.gpx
# Highway speed with all the bells and whistles
gps-highway --bearing --monitor --stats route.gpx
# Test a specific section (when your 2000-point route has one weird spot)
gps-drive --start 100 --end 150 route.gpx
# Broadcast to all emulators (chaos engineering for location services)
gps-drive --all-emulators route.gpx
# Reverse route (for testing "return journey" functionality)
gps-jog --reverse route.gpx| Command | Speed | Use Case | Real-World Equivalent |
|---|---|---|---|
--walking |
3s delay | Fitness apps, AR games | Casual stroll while checking phone |
--jogging |
2s delay | Running apps | Light jog (not quite marathon pace) |
--cycling |
1s delay | Bike sharing apps | Leisurely bike ride |
--driving |
0.5s delay | Navigation, ride-sharing | City driving with traffic |
--highway |
0.2s delay | Long-distance routes | Highway driving (don't test this on walking routes) |
--teleport |
0.1s delay | Debug/testing | Quantum tunneling (results may vary) |
# Watch your simulation like a GPS hawk
gps-monitor route.gpxShows current coordinates, bearing, progress, and how much of your life you've spent testing location features.
# Because someone will ask "how fast can it go?"
./routing.sh --profile --stats route.gpx# Get the nerdy details about your route
./routing.sh --stats route.gpxOutputs: total points, distance, average spacing, and probably more numbers than you wanted.
After running --install-aliases, you get these shortcuts:
gps-sim # Basic simulator
gps-walk # Walking speed (3s delay)
gps-jog # Jogging speed (2s delay)
gps-bike # Cycling speed (1s delay)
gps-drive # Driving speed (0.5s delay)
gps-highway # Highway speed (0.2s delay)
gps-debug # Debug mode (fast + verbose)
gps-loop # Walking loop mode
gps-monitor # Driving with real-time display
gps-test # Dry run (parse only)# Create a simple test route
cat > test.gpx << 'EOF'
<?xml version="1.0"?>
<gpx version="1.1">
<trk>
<trkseg>
<trkpt lat="37.7749" lon="-122.4194"></trkpt>
<trkpt lat="37.7849" lon="-122.4094"></trkpt>
<trkpt lat="37.7949" lon="-122.3994"></trkpt>
</trkseg>
</trk>
</gpx>
EOF
# Test it
gps-test test.gpx- Open Google Maps (or your app) in the emulator
- Run
gps-drive test.gpx - Watch the location dot move like magic โจ
- Feel unreasonably proud of automating something you used to do manually
# Check what's actually running
adb devices
# Make sure emulator is started
emulator -avd YourAVDNameYour GPX file might be using <wpt> (waypoints) instead of <trkpt> (track points). The script handles this, but you can check:
grep -c "trkpt\|wpt\|rtept" your_file.gpxYou forgot to reload your shell after installing aliases:
source ~/.bashrc # or ~/.zshrcRun with verbose mode to see what's happening:
./routing.sh -v route.gpxWelcome to macOS! Upgrade your bash:
brew install bash
echo /opt/homebrew/bin/bash | sudo tee -a /etc/shells
chsh -s /opt/homebrew/bin/bash# Don't put scripts in folders with spaces (trust me on this)
mkdir -p ~/dev/tools
mv routing.sh ~/dev/tools/gps-simulator.sh
# Create a routes folder
mkdir -p ~/dev/routes
# Put your GPX files there# Always dry-run first (learn from my pain)
gps-test new_route.gpx
# Start with slow speeds for debugging
gps-walk problematic_route.gpx
# Use loop mode for endurance testing
gps-walk --loop stress_test_route.gpx &
# Leave it running overnight, see what breaks# Test multiple apps simultaneously
gps-drive route.gpx &
# Open Maps, Uber, your app, etc. in emulator
# All see the same GPS feedQ: Why not build a GUI?
A: I was going to make a beautiful KMM desktop app, but then I realized this CLI already does everything you need. Plus, I spent the GUI development time optimizing the script instead. Also, my designer quit when I showed them my mockups.
Q: Can I use this for iOS Simulator?
A: This is Android-specific (adb commands). It just I don't like routing in Android studio it keep showing me loading saved route, like okay one more problem to solve
https://issuetracker.google.com/issues/141731672 link of the issue
Q: Does this work with real devices?
A: It uses adb emu geo fix, which is emulator-specific. For real devices, you'd need mock location apps and different commands.
Q: Can I contribute?
A: Absolutely! Though fair warning: I have opinions about code style and will probably suggest you refactor everything. It's nothing personal.
Q: Why bash instead of Python/Node/Rust/Go/etc?
A: Because sometimes the right tool is the boring tool that works everywhere and doesn't require a package manager. Also, I like living dangerously.
- Small routes (< 100 points): Instant parsing, buttery smooth playback
- Medium routes (< 1000 points): 1-2 second startup, no noticeable lag
- Large routes (> 5000 points): 5+ second parsing, but smooth once running
- Huge routes (> 10000 points): Consider using
--startand--endto test sections
- xmlstarlet: For making XML parsing not completely terrible
- adb: For being the Swiss Army knife of Android development
- My cat: For providing quality assurance by randomly walking across my keyboard
- Stack Overflow: For existing
- Coffee: The real MVP
MIT License - because sharing is caring, and I'm not important enough to need a complicated license.
- KMM desktop app (when I have 3 months and a good reason)
- Route recording mode (capture real GPS traces)
- Integration with popular testing frameworks
- World domination (stretch goal)
Remember: Good tools solve real problems. Great tools solve real problems with style. This tool solves real problems with style and probably too many command-line options.