Bluetooth LE startNotification not working

When I do a ble.read() it works, but ble.startNotification() does not. Do you know why?

Phone is a Galaxy S6. Peripheral is a Raspberry Pi with my own custom Bluetooth code. Notification works as expected in the LightBlue app. I can see the identical output from read() in LightBlue when subscribing to notify.

import { Injectable } from '@angular/core';
import { BLE } from '@ionic-native/ble/ngx';
import { NgZone } from '@angular/core';
import { Platform } from '@ionic/angular';

@Injectable({
  providedIn: 'root'
})
export class BtoothService {
  private device_id: string;
  private serviceUUID = '2FE11A47-E4B8-4522-9CFF-AA729B8215C0';
  private statusUUID = '2FE11A47-E4B8-4522-9CFF-AA729B8215CF';

  constructor(
    private ble: BLE,
    private ngZone: NgZone,
    private platform: Platform,
  ) {
    console.log('constructor()');
    this.platform.ready().then(() => {
      console.log('platform.ready()');
      this.ble.enable().then(() => {
        console.log('ble.enable()');
        this.ble.isEnabled().then(() => {
          console.log('ble.isEnabled()');
          this.ble.startScan([]).subscribe(
            device => this.onDeviceDiscovered(device),
            error => {
              console.log('connect() error: ', JSON.stringify(error));
            });
        });
      });
    });
  }

  bytesToString(buffer) {
    return String.fromCharCode.apply(null, new Uint8Array(buffer));
  }

  onDeviceDiscovered(device) {
    console.log('device.name: ', JSON.stringify(device.name));
    if (!device.name) {
      return;
    }
    if (device.name.startsWith('SecureCoop-')) {
      console.log('device.name.startsWith(SecureCoop-)');
      this.ngZone.run(() => {
        console.log('ngZone.run()');
        this.device_id = device.id;
        this.ble.refreshDeviceCache(device.id, 1000);
        this.ble.connect(device.id).subscribe(peripheral => {
          console.log('ble.connect() peripheral: ', JSON.stringify(peripheral));
          this.ble.isConnected(device.id).then(() => {
            console.log('ble.isConnected()');
            this.ble.read(this.device_id, this.serviceUUID, this.statusUUID).then(status => {
              status = this.bytesToString(status);
              console.log('read() status: ', JSON.stringify(status));
            },
              error => {
                console.log('read() error: ', JSON.stringify(error));
              });
            this.ble.startNotification(this.device_id, this.serviceUUID, this.statusUUID).subscribe(status => {
              status = this.bytesToString(status);
              console.log('startNotification() status: ', JSON.stringify(status));
            },
              error => {
                console.log('startNotification() error: ', JSON.stringify(error));
              }
            );
            console.log('ble.stopScan()');
            this.ble.stopScan();
            console.log('Done');
          });
        });
      });
    }
  }
}
2020-08-19 12:12:49.578 17668-17668/com.ionicthemes.ionic5fullapp I/Capacitor/Console: File: http://localhost/main-es2015.js - Line 923 - Msg: read() status:  "[84, 101, 115, 116, 105, 110, 103]"
2020-08-19 12:12:49.710 17668-17668/com.ionicthemes.ionic5fullapp I/Capacitor/Console: File: http://localhost/main-es2015.js - Line 929 - Msg: startNotification() status:  "\u0000\u0000"

LightBlue has no problem with notify/subscribe.

Hi,
I had the same problem, you can solve it by reading this. Solved in https://github.com/ionic-team/ionic-native/issues/3511
“There is a breaking change. Now data are at index 0 of returned array.”
Change your bytesToString like this

 bytesToString(buffer) {
    var data = new Uint8Array(buffer[0]);
    return String.fromCharCode.apply(null, data);
  }
1 Like