---
updatedAt: 2025-11-07T19:54:47.000Z
agentTools:
  projectIndex: https://developer.validic.com/llms.txt
---

# Bluetooth Operations

Native Android ==> Bluetooth module

## Pair

Check if a BluetoothPeripheral requires pairing by calling:

```
BluetoothPeripheral peripheral = // ...  
boolean pairBeforeRead = peripheral.requiresPairing();  
If it does, the user must pair the peripheral before they can take a reading.

BluetoothPeripheral peripheral = // Choose a perpheral from the supported perpherals list  
BluetoothPeripheralControllerListener listener = new BluetoothPeripheralControllerListener() {  
        @Override  
        public void onPeripheralDiscovered(@NonNull BluetoothPeripheralController controller, @NonNull BluetoothPeripheral bluetoothPeripheral, @NonNull BluetoothDevice bluetoothDevice) {  
           // A BluetoothDevice matching the BluetoothPeripheral has been discovered.  
        }   
    @Override
    public boolean onSuccess(@NonNull BluetoothPeripheralController controller, @NonNull BluetoothPeripheral bluetoothPeripheral, @NonNull BluetoothDevice bluetoothDevice, @NonNull List<Measurement> list) {
        // Pairing was successful using the BluetoothPeripheral profile.
        // Some devices support previous storing historical data automatically transmit previously stored Records.
        return true; // automatically submit records collected to the Validic
    }

    @Override
    public void onFail(@NonNull BluetoothPeripheralController validicBluetoothPeripheralController, @NonNull BluetoothPeripheral bluetoothPeripheral, @Nullable BluetoothDevice bluetoothDevice, @NonNull final ValidicBluetoothException error) {
        if (!isCanceling) {
            instructions.post(() -> fail(error.getError()));
        }
    }
};

BluetoothPeripheralController controller = new BluetoothPeripheralController();  
controller.pairPeripheral(peripheral, listener);

String pairingInstructions = peripheral.getPairingInstruction();  
// Display the pairing Instructions to the user
```

<br />

## Read

Once you are ready to read from a peripheral, the process is fairly similar to the pairing process. You’ll want to first show the peripheral’s instructions and eventually show the reading instructions once onPeripheralDiscovered is called.

```
BluetoothPeripheral peripheral = // The peripheral you want to read from  
BluetoothPeripheralControllerListener listener = new BluetoothPeripheralControllerListener(){
  
@Override
public void onPeripheralDiscovered(final BluetoothPeripheralController peripheralController, BluetoothPeripheral peripheral, BluetoothDevice bluetoothDevice) {
    // Display the reading Instructions to the user
}

@Override
public void onFail(final BluetoothPeripheralController peripheralController, BluetoothPeripheral peripheral, BluetoothDevice bluetoothDevice, ValidicBluetoothException exception) {
			BluetoothError error = exception.getError();
    switch (error) {
        case BluetoothError.BluetoothTurnedOff:
            Toast.makeText(getApplicationContext(), "Your bluetooth is off!", Toast.LENGTH_LONG).show();
            break;
        case BluetoothError.NoUser:
            Toast.makeText(getApplicationContext(), "You have not started the session yet!", Toast.LENGTH_LONG).show();
            break;
        case BluetoothError.Cancelled:
            Toast.makeText(getApplicationContext(), "Reading has been cancelled", Toast.LENGTH_LONG).show();
            break;
    }

    Log.e("Error", error.getMessage());
}

@Override
public boolean onSuccess(final BluetoothPeripheralController peripheralController, BluetoothPeripheral peripheral, BluetoothDevice bluetoothDevice, List<Measurement> measurements) {
  // Measurements were collected from a BluetoothDevice using a BluetoothPeripheral's profile
  return true; // Automatically submit measurements collected to the Validic Mobile API
}
  };

String instruction = peripheral.getInstruction();  
// Display the instruction to the user

BluetoothPeripheralController controller = new BluetoothPeripheralController();  
controller.readFromPeripheral(peripheral, listener);
```

<br />

### Read With A Filter Applied

`readFromPeripheral` will scan for a BluetoothPeripheral and attempt to read from the first `BluetoothDevice` that it finds that matches the `peripheral` parameter. To limit reads to specific instance of a `BluetoothDevice`, you can use `readFromPeripheral(peripheral, options, listener):`. This may be useful for situations in which more than one of the same peripheral might be in use at the same time.

The options parameter accepts an instance of `BluetoothOperationOptions`. Set `options.allowedMACAddresses` to a list of BluetoothDevice MAC Addresses that you want to allow reads from. Bluetooth Scans with MAC addresses not on the list will be ignored. If the list is `null`, no peripherals will be ignored; if the list is empty, all peripherals will be ignored. MAC addresses can be retrieved from the pair and read callbacks with e.g. `bluetoothDevice.getAddress()`.

Here's an example that captures the BluetoothDevice MAC address from a successful pairing and then uses it in a read call.

```kotlin
// Capture `bluetoothDevice.address` in pairing delegate method
val controller = BluetoothPeripheralController()
var recentMACAddress: String? = null
val peripheral = // a BluetoothPeripheral
val listener = object : BluetoothPeripheralControllerListener {
  override fun onPeripheralDiscovered(peripheral: BluetoothPeripheral, bluetoothDevice: BluetoothDevice) {
    // Display the pairing instructions to the user
  }
  override fun onFail(peripheral: BluetoothPeripheral, bluetoothDevice: BluetoothDevice, exception: ValidicBluetoothException) {
    // Handle pairing failure
  }
  override fun onSuccess(peripheral: BluetoothPeripheral, bluetoothDevice: BluetoothDevice, measurements: List<Measurement>): Boolean {
    // Capture the MAC address for later use
    recentMACAddress = bluetoothDevice.address
    return true // Automatically submit measurements collected to the Validic Mobile API
  }
}
controller.pairPeripheral(peripheral, listener)

// Later, to read from that specific peripheral

val options = this.recentMACAddress?.let { BluetoothOperationOptions(allowMACAddreses = listOf(it)) }
controller.readFromPeripheral(peripheral, options, object: BluetoothPeripheralControllerListener {)
  override fun onPeripheralDiscovered(peripheral: BluetoothPeripheral, bluetoothDevice: BluetoothDevice) {
    // Display the reading instructions to the user
  }
  override fun onFail(peripheral: BluetoothPeripheral, bluetoothDevice: BluetoothDevice, exception: ValidicBluetoothException) {
    // Handle reading failure
  }
  override fun onSuccess(peripheral: BluetoothPeripheral, bluetoothDevice: BluetoothDevice, measurements: List<Measurement>): Boolean {
    // Handle successful read
    return true // Automatically submit measurements collected to the Validic Mobile API
  }
})
```

<br />

## Custom global error handler

If using the bluetooth module, a global error handler will be registered via: `RxJavaPlugins.setErrorHandler()`.

If you want to customize this handler, it can set by calling `RxJavaPlugins.setErrorHandler(handler)` at any point.

Please review the [RxJava 2.x error handling](https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling) documentation for more information about this handler.

<br />

## Special Considerations

Most supported Bluetooth devices function similarly and you can follow the instructions in [Bluetooth permissions](https://helpdocs.validic.com/docs/native-android-mobile-inform-sdk-bluetooth-permissions), [Bluetooth Operations](https://helpdocs.validic.com/docs/native-android-mobile-inform-sdk-bluetooth-operations#pair) and [Passive Read](https://helpdocs.validic.com/docs/native-android-mobile-inform-sdk-bluetooth-passive-read) to work with them.

However, a few of our supported devices have additional requirements and/or considerations that you need to be aware of. Those are covered in [Bluetooth Behavior](https://helpdocs.validic.com/docs/native-android-mobile-inform-sdk-bluetooth-behavior).