mock location & virtual camera

Fake the fix.
Keep the test real.

Relocation is a developer test rig: a single Flutter shell over a native Kotlin mock-location service, plus a virtual camera that feeds your own app. Free maps, no API key, and nothing hidden behind a service you rent.

Android 8.0+ · min SDK 26

00:00:00
Relocation MOCK · 1 Hz
Vehicle · Car 31.7295° N, 74.4163° E
01

A rig you own,
not a service you rent.

Every part of the stack is inspectable: an open map style, a documented native service, and errors that come back as error codes.

01

Road-constrained GPS

Pick a point or a route on OpenFreeMap. A* routing keeps the vehicle on roads, and the native service publishes a mock fix every 500–10000 ms.

02

App-private virtual camera

A bundled Camera1 module feeds a virtual stream to the app under test. It is scoped through LSPosed only where you choose to enable it.

03

Four tabs, one channel

Map, Virtual Camera, Cam and Settings. The Flutter UI never talks to Android directly — everything crosses a MethodChannel.

No map API key

OpenFreeMap styles — liberty, positon, dark — ship without a key, an account or usage limits.

Typed errors

PERMISSION_DENIED, MOCK_APP_NOT_SELECTED and LOCATION_UNAVAILABLE are real codes, not toast text.

Root optional

The core mock-location flow needs no root at all. Root lives inside a guest, only for the camera hook.

03

Four tabs,
one native service.

A single Flutter shell over a native Kotlin mock-location service. The UI never talks to Android directly — everything crosses a MethodChannel that returns typed errors.

Interactive 3D map & GPS movement

The default screen. The camera centres on the real device fix, the vehicle marker sits on it, and a running session publishes a mock fix every 500–10000 ms (1 s by default).

  • Five vehicles with per-vehicle speed limits and acceleration
  • Hold LEFT/RIGHT and FWD/BACK; the first press auto-starts the session
  • Destination by long-press, tap in pick-on-map mode, or typed lat/lon with -90..90 / -180..180 validation
  • Camera follow with auto bearing; Recenter re-fetches the fix and re-centres
  • Reset location in Settings snaps back to the real fix

Setup in four steps

On a normal, non-rooted phone the core app needs no root at all.

  1. 1

    Enable Developer Options

    Settings → About phone → tap Build number seven times, then System → Developer options ON.

  2. 2

    Select the mock location app

    Developer options → Select mock location app → Relocation. The app shows a NOT SELECTED badge and an Open Developer Settings button until this is done.

  3. 3

    Grant the permissions

    Location, camera, storage on Android 8–9, and notifications on Android 13+. Each step is verified by Android and re-checked by the app.

  4. 4

    Exempt battery optimisation

    Battery settings → All apps → Relocation → Don’t optimise, so the foreground service is not killed while the app is in the background.

04

Run the whole rig
inside an Android clone.

Virtual Master gives you a disposable Android 9 guest where you can install a rooted runtime without touching the host phone.

Host and guest are different worlds

The physical phone is the host; the Virtual Master VM is the guest. The rules that matter:

  • Relocation installed on the host and Relocation imported into the guest are two separate installations
  • Permissions, selected media, target lists and settings are per installation
  • The guest framework only affects processes inside that guest
  • Your target camera app must live in the same guest — a guest Relocation cannot replace the host’s camera app
  • Guest output is not automatically copied to the host Gallery; use the VM’s own export or share

Virtual Master APK setup

  1. 1

    Install the Virtual Master APK

    Install Virtual Master on the host phone and open it once so it can provision its runtime.

  2. 2

    Create the guest

    Create an Android 9 / API 28 arm64 guest. The verified configuration is Virtual Master 3.2.85 on an arm64 guest running ROM 1059.

  3. 3

    Import Relocation

    Use the VM import flow (Import → folder) to install the Relocation APK inside the guest, then complete onboarding inside the guest.

  4. 4

    Import Magisk

    Import the official Magisk release through Virtual Master’s own import UI. The VM exposes its own bundled Magisk runtime and adds a Magisk Enabled toggle in VM Settings.

  5. 5

    Enable Zygisk and restart the VM

    In the guest: Magisk → Settings → Zygisk ON. Then use the VM’s outer Restart VM — Restart, Reset, Repair, Restore and Delete VM are different operations.

  6. 6

    Install LSPosed and set its scope

    Install the LSPosed module from storage, enable Zygisk, then scope it to the camera target app only.

A manager icon being installed is not proof that the root runtime is active. Confirm Zygisk: Yes on the guest Magisk Home screen and check the runtime version in use.

Video thumbnail: Virtual Master Android Clone — how to activate a virtual Android machine on Android Virtual Master

Virtual Master Android Clone — how to activate a virtual Android machine on Android

Use it to create the guest first; the Relocation import happens inside the VM.

Verified configuration
Virtual Master3.2.85
Guest OSAndroid 9 / API 28, arm64, ROM 1059
Guest Magisk runtime25200 (6066b5cf)
Working arrangementphysical phone → Virtual Master guest → Relocation + compatible framework + authorised Camera1 target
05

Scope the camera hook
to the app you are testing.

Installed and enabled is not the same as scoped — and a scoped module is not the same as a verified capture.

Install it the supported way

  1. 1

    Install as a Magisk module

    Guest Magisk → Modules → Install from storage and pick the LSPosed archive. Follow the official LSPosed setup for the correct flavor.

  2. 2

    Enable Zygisk and reboot

    Zygisk must be on and the runtime must actually restart for the module to load.

  3. 3

    Pick the scope

    Open the LSPosed manager and select only the app under test. System Framework, Android System, System UI, Magisk and unrelated apps are not required for camera replacement.

  4. 4

    Verify per target

    For each target: preview appears, the JPEG callback arrives, and the file lands in the Gallery. These are three separate checks.

06

Root the guest,
not the phone.

Magisk provides the Zygisk runtime that LSPosed needs. In the tested setup the root runtime lives inside a Virtual Master guest, so the host phone is never unlocked, flashed or rooted.

Guest

Inside the guest

  • Import the official Magisk release through Virtual Master’s own UI
  • Confirm the runtime the guest actually uses — the VM ships its own bundled Magisk, and an imported APK’s version can differ from the VM runtime version
  • Magisk → Settings → Zygisk ON, then verify Zygisk: Yes on Magisk Home
  • Restart with the VM’s outer Restart VM; an in-guest reboot can leave the guest core process in a warning state
Host

Before you touch a physical phone

  • Relocation never triggers a data wipe, and switching the module on or off is not a factory reset
  • Unlocking a physical bootloader through Android’s documented flow can erase device data
  • Do not treat “zero-wipe root guaranteed” as a fact; an unlocked device still carries firmware-specific risk
  • This project’s own setup never unlocked, flashed or rooted the host bootloader
07

Questions that
come up first.

Answers reflect the current implementation. Menu labels and compatibility change with Android and OEM versions.

Do I need root for the core app?

No. Mock location and the internal virtual camera work on a normal non-rooted phone. Root is only involved when you want the embedded Camera1 module to reach other camera apps, which is the LSPosed / Magisk path described above.

How do I install the APK on a second device?

Copy build/app/outputs/flutter-apk/app-debug.apk to the target phone and open it with a file manager, allowing “Install unknown apps” for that installer only. Choose Update over an existing installation — do not uninstall or clear storage. The signing certificate must match: a debug key generated on another computer is not automatically the same key. If you see INSTALL_FAILED_UPDATE_INCOMPATIBLE or “App not installed”, check the package and signing key first; uninstalling is not the first solution.

Does the app bypass Android security?

No. Android requires you to explicitly select Relocation as the mock location app in Developer Options. ACCESS_MOCK_LOCATION is declared only so the app appears in that list; it is never granted automatically. Root, hidden-API and anti-spoofing tricks are deliberately not used.

What happens after a reboot or if the process is killed?

The simulation does not restart by itself. There is no reboot receiver. The app is a foreground service that keeps publishing while the app is backgrounded, and it re-syncs to the real fix when you reset the location in Settings.

Why does another camera app still show the real camera?

Because that path needs the framework, the scope and a verified target. “Module available” or “module ready” never means “active in every app”. Check three things separately for each target: the preview appears, the JPEG callback arrives, and the file is saved. On a standard non-rooted phone the current build cannot hand selected media to another ordinary camera app.

Does Virtual Master replace my host camera app?

No. A guest Relocation only affects processes inside the guest. The target camera app has to be installed in the same guest, and the guest framework only applies to that guest. Guest Gallery output is not automatically copied to the host Gallery.

Which Android versions are supported?

Relocation requires Android 8.0 / API 26 or newer. The experimental Camera2 backend is documented for Android 9 only and is default-off. The verified Virtual Master configuration is an Android 9 / API 28 arm64 guest. Compatibility with other ROMs, OEMs and Android versions has to be re-tested on each device.

Is the map service free?

Yes. The map uses OpenFreeMap styles with no API key, no usage limits and no account. Road data comes from OpenStreetMap via Overpass for the road graph and A* routing.

Can I use this on someone else’s phone or for anything that misleads people?

Only on devices you own or control, and only for testing your own software. Relocation is a test rig: it publishes a mock fix that Android visibly flags, and it is not intended to deceive third parties, evade location-based policy, or gain access to services you are not authorised to test.

Where do I find the full documentation?

In the repository under docs/: the complete setup and troubleshooting guide, the native camera API notes, the Camera2 compatibility and limits, the virtual camera module reference, and the executed verification results. Every device-specific limitation is recorded there rather than smoothed over.

Use it on devices you control

Relocation is a developer test rig. It publishes a mock location that Android flags in the system UI, and it never bypasses the platform’s own permission model. Use it on hardware you own or are authorised to test.

Read the FAQ

Take the rig
for a drive.

One APK, four tabs, and a map that costs nothing. Set it up in about five minutes.

Android 8.0+ · min SDK 26 · com.relocation.app