Blazor Web Bluetooth – Android – Part 2

Earlier Post

Welcome back! In the earlier post we already managed to connect and read characteristics from a BLE device. But had it only logged to console.

Now let’s also display it on GUI.

Call Blazor from Javascript

Let’s first add some more Code

@page "/blue"
@implements IDisposable
@inject IJSRuntime JS

<h3>Bluetooth</h3>
<button @onclick="GetDevices">GetDevices</button>
<div>
  @Message
</div>

@code{
  protected string Message = "Nothing yet";
  private DotNetObjectReference<Bluetooth>? objRef;

  protected override void OnInitialized()
  {
    objRef = DotNetObjectReference.Create(this);
  }

  public async Task GetDevices()
  {
    await JS.InvokeVoidAsync("setNetRef", objRef);
    await JS.InvokeVoidAsync("ConnectBluetooth");
  }

  [JSInvokable]
  public async Task Status(string value)
  {
    Console.WriteLine($"Status '{value}'");
    Message = value;
    StateHasChanged();
  }

  public void Dispose()
  {
    objRef?.Dispose();
  }
}
let netRef;
async function setNetRef(ref) {
  netRef = ref;
}

async function ConnectBluetooth() {
  if(!navigator.bluetooth) {
    console.error("No access to bluetooth");
    return;
  }

  let device = await navigator.bluetooth.requestDevice({
    filters: [{
      services: ['00000001-5239-4069-806d-7e5c97393755'],
    }]
  });
  console.log({device});

  let server = await device.gatt.connect();
  console.log({server});

  let service = await server.getPrimaryService('00000001-5239-4069-806d-7e5c97393755');
  console.log({service});

  let charac_deviceTime = await service.getCharacteristic('00000002-5239-4069-806d-7e5c97393755');
  console.log({charac_deviceTime});

  charac_deviceTime.addEventListener('characteristicvaluechanged', (event) => {
    console.log(event.target);

    let value = event.target.value.getFloat32(0, true);
    console.log('> Characteristic is ' + value);

    if(netRef) {
      netRef.invokeMethodAsync('Status', 'Charac is: ' + value);
    }
  });

//  console.log((await charac_deviceTime.readValue()).getFloat32(0, true));
  await charac_deviceTime.startNotifications();
}

Rebuild, run and load, and we see that on the page the Characteristic value is displayed.

As well as lots of logging

So what is happening in the background?

To allow Javascript to call Blazor Webassembly functions, we need to provide a reference to the Blazor instance. This is done by creating a reference to this as objRef and then handing it over to Javascript by invoking setNetRef function.

Furthermore we create a javascript accessible or exposed function Status that takes a string as argument and sets displayed Message. Unfortunately, the HTML Element is not automaticly updated, so rerender needs to be triggered manually by calling StateHasChanged().

Final code can be found here https://github.com/sukapx/tryout_blazor_webbluetooth/tree/49c058c5da877eb1e2a146bb8a8207d02911f793

Leave a Reply

Your email address will not be published. Required fields are marked *