RxCentral: Uber’s Open Source Library for Seamless Bluetooth Integrations
3 December 2019 / Global
At Uber, we innovate through products that connect users to both the digital and physical worlds, making services such as transportation and food delivery as easy as possible. An increasing number of these products share a common need: to discover, connect, and communicate using Bluetooth. To enable a new generation of innovations, we need to make Bluetooth easier for engineers to implement and enable cross-platform designs that can be repeated across applications.
Enter RxCentral, Uber-developed open sourced libraries for Android (RxCentralBle) and iOS (RxCBCentral), to communicate with Bluetooth LE peripherals in a reliable, repeatable fashion via a platform-agnostic, reactive design. RxCentral’s reactive functions can be used individually or in combination to orchestrate elegant, reactive user experiences with Bluetooth LE peripherals.
Our initial integration connects our driver-partners’ phones with our next-generation Uber beacon. Beacon combines color-matching technology with an advanced sensor suite to enhance the experience of both driver-partners and riders. To enable its complex features, beacon requires high throughput and reliability that pushes the limits of Bluetooth: RxCentral delivers this functionality, and in the process, improves transportation experiences on our platform for riders and driver-partners alike, who can only use Bluetooth in-app while leveraging beacon.
RxCentralBle at a glance
RxCentralBle allows us to rapidly implement four primary functions: detect state, scan, connect, and communicate. Each function is performed in a reactive manner; subscribe to enable functionality and dispose to stop, letting engineers design services that cleanly integrate into a modern, reactive application.
Detect Bluetooth
The BluetoothDetector detects an Android device’s Bluetooth state, determining if Bluetooth is live and available to connect:
BluetoothDetector bluetoothDetector;
Disposable detection;
// Use the detector to detect Bluetooth state.
detection = bluetoothDetector
.enabled()
.subscribe(
enabled -> {
// Tell the user to turn on Bluetooth if not enabled
}
);
In our reactive paradigm, we can dispose our detection subscription to stop detection:
// Stop Bluetooth detection.
detection.dispose();
Scan
The Scanner tells the device to scan for Bluetooth LE peripherals advertising their availability:
Scanner scanner;
Disposable scanning;
// Use the scanner to scan for advertising peripherals.
scanning = scanner
.scan())
.subscribe(
scanData -> {
// We found the peripheral we are looking for
}
);
Disposing the scanner subscription stops scanning for other Bluetooth peripherals, automatically cleaning up after ourselves and releasing all scanning resources:
// Stop scanning.
scanner.dispose();
Connect
RxCentralBle’s code for establishing a connection is similarly easy to using the BluetoothDetector and Scanner. Building on the above example, we can scan for devices and connect to them with a single ConnectionManager function:
ScanData scanData;
ConnectionManager connectionManager
PeripheralManager peripheralManager;
Disposable connection;
// Connect to a device.
connection = connectionManager