Skip to content

Android Integration

The SensorChaos Android agent intercepts LocationManager calls in your app and replaces them with CLI-injected data. Integration takes one line of Kotlin and a Gradle dependency — no other changes to your production code.

In your app module’s build.gradle.kts, add the agent as a debugImplementation dependency only:

First, add the SensorChaos Maven repository to your settings.gradle.kts:

dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://releases.sensorchaos.com/maven") }
}
}

Then add the agent as a debugImplementation dependency:

dependencies {
debugImplementation("dev.sensorchaos:agent:0.1.0")
}

This ensures the agent classes are completely absent from release builds. No authentication required.

In your Application subclass, override attachBaseContext and wrap the base context:

import android.content.Context
import dev.sensorchaos.agent.SensorChaos
class MyApplication : Application() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(SensorChaos.wrap(base))
}
}

That’s the only change required in your application code. The SensorChaos.wrap() call returns a ChaosContextWrapper which overrides getSystemService() to return a proxied LocationManager whenever the agent’s TCP server has an active session. When no CLI session is running, all calls pass through transparently to the real system services.

3. Add the permission to the debug manifest

Section titled “3. Add the permission to the debug manifest”

Create or update src/debug/AndroidManifest.xml to include the mock location permission:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
</manifest>

This permission is only present in the debug variant because it lives in src/debug/.

4. Enable mock location in developer options

Section titled “4. Enable mock location in developer options”

On the device or emulator:

  1. Open Settings → Developer options
  2. Scroll to Select mock location app
  3. Select your debug app from the list

This grants the app permission to receive mock location data via the TestProvider API.

When a SensorChaos CLI session starts, it establishes an ADB port-forward from the host machine to port 19847 on the device. The CLI then connects a TCP socket and sends JSON Lines commands:

{"cmd":"location","lat":25.197,"lng":55.274,"accuracy_m":5.0,"satellites":12}

The agent responds to each command with a JSON Lines ack:

{"ok":true}

The agent also supports a status query that returns the current injection state:

{"cmd":"status"}

Response:

{"ok":true,"status":{"injecting":true,"location":{"lat":25.197,"lng":55.274,"accuracy_m":5.0,"satellites":12},"sensors":{"accelerometer":[0.1,-0.2,9.8]}}}

status.location is null when signal loss is active or no fix has been sent. status.sensors is a map of sensor type to the last-written values array.

The ChaosTcpServer running inside the agent receives these commands and passes them to LocationInjector, which uses the Android TestProvider API to push the injected position into the LocationManager pipeline. All registered LocationListener callbacks in the app receive the injected data as if it came from the real GPS hardware.

When the CLI session ends or the connection drops, the agent stops injecting and the real GPS resumes automatically.

After installing the agent in your debug build and running the app on a device, verify the full injection chain with:

Terminal window
sensorchaos check --agent

This connects to the agent, reports whether location and sensor injection are available on the target device, and flags any missing permissions or unsupported APIs before you run your first scenario.

The agent includes a ChaosContentProvider that initialises the TCP server automatically when the app process starts — no manual onCreate() call is required. This means the agent is ready to accept connections as soon as the app launches, even before your Application.onCreate() runs.

If you want GPS injection on a real Android device without modifying your app, install the SensorChaos ADB helper APK. It requires no changes to your application code and works with any app that has mock location enabled in Developer Options.

The helper is a minimal APK (dev.sensorchaos.adb) that registers a LocationManager TestProvider named sensorchaos and exposes it via a BroadcastReceiver. When the CLI runs without --agent, it sends:

Terminal window
adb shell am broadcast -a dev.sensorchaos.MOCK_LOCATION \
--ed lat 25.197 --ed lng 55.274 --ef accuracy 5.0

The receiver starts a foreground service that keeps the TestProvider alive and updates it with each broadcast. When the scenario ends, the CLI sends am stop-service and the provider is removed, restoring real GPS.

  1. Download adb-helper-release.apk from the latest GitHub release.
  2. Install it:
    Terminal window
    adb install adb-helper-release.apk
  3. On the device: Settings → Developer options → Select mock location app → choose SensorChaos ADB Helper.
  4. Run a scenario without --agent:
    Terminal window
    sensorchaos run gnss/gulf-spoofing-2026 --device <serial>

In normal use the agent runs for the lifetime of the app process and there is no need to shut it down manually. If you need to tear it down mid-process — for example, between instrumented test cases — call:

SensorChaos.stop()

This stops the TCP server, removes the location TestProvider, releases sensor resources, and clears the singleton. SensorChaos.wrap() may be called again afterwards to reinitialise.

In release builds the debugImplementation dependency is not included, so SensorChaos, ChaosContextWrapper, and all agent classes are absent from the APK. The attachBaseContext override calling SensorChaos.wrap(base) will fail to compile in a release build that doesn’t have a release stub — but because debugImplementation is excluded at the Gradle variant level, the debug-only code is simply not compiled for release variants. No runtime checks or reflection are involved.