SimBLE in the Android Emulator
Develop and test a Bluetooth LE app end-to-end with no physical hardware. Your app runs in the Android Studio Emulator; netsim is the radio between it and a scene of simulated devices; SimBLE provides those devices — real GATT peripherals your app scans, connects to, pairs with, and reads and writes, exactly as it would a real accessory. Deterministic, reproducible, and always available.
Why this matters
Testing a BLE app normally means a drawer of accessories to charge, pair, and keep in range — and behaviours you can't stage on demand (a device that drops mid-notification, sends a stale value, or misbehaves at exactly the wrong moment). With this setup the accessory is software: it behaves the same way every run, it's always there, and it can misbehave on command when that's what your test needs.
What each piece does
- The Emulator (AVD) runs your app. Its virtual Bluetooth controller is wired to netsim instead of a real radio.
- netsim is the Android emulator's network simulator: the simulated PHY that carries packets between the emulator and everything else on the scene, plus a 3D position model for movement and ranging.
- SimBLE supplies the devices your app talks to. netsim can host simple beacons on its own, but not full GATT peripherals — services, characteristics, descriptors, pairing, notifications. That's SimBLE's job: the real devices, defined in a few lines of Rhai.
Step by step
- 1. Install the canary-channel emulator (37.2.5+ — the stable
emulator's netsim doesn't have the WebSocket endpoint yet):
~/Library/Android/sdk/cmdline-tools/latest/bin/sdkmanager --channel=3 emulator - 2. Start netsim with its WebSocket frontend:
~/Library/Android/sdk/emulator/netsimd --logtostderr --no-shutdown --ws-port 7681 - 3. Launch your AVD from Android Studio and run your BLE app on it. The emulator joins the same netsim scene automatically.
- 4. Add SimBLE devices to the scene. Each connects to netsim
over
ws://localhost:7681, naming itself in the URL:
or build your own from the Rust API or a Rhai script (see the Playground).cargo run --example netsim_smoke # one device, HCI round-trip cargo run --example netsim_two_devices # two devices discovering each other - 5. Test. Your app scans, finds the SimBLE peripherals, connects, and exercises them — the same code paths it would run against real hardware.
~/Library/Android/sdk/emulator/netsim devices, and capture traffic
with netsim capture — the same tooling the emulator uses.
Managing simulated devices — a web page, not a CLI
Rather than script devices by hand, the Scene creator is a visual device manager: add scripted servers, scanners, and clients, edit their Rhai, and inspect their GATT. Today it drives an in-browser controller; pointed at netsim (a backend selector, like the other pages have) it becomes the surface for managing the emulator's scene — the modern, web form of an "add simulated BLE devices" panel, no IDE plugin required. Open it beside Android Studio, add the devices your app expects, and iterate.
Reproducibility
Because each device is a short Rhai script, the script is the fixture. The same file that stages a scenario by hand ships into CI unchanged, so an emulator test and a CI run exercise the identical device — no drift between "what I tested against" and "what CI runs".