ionic 4 bluetooth low energy - sample code - List BLE Devices

January 16, 2020 12 comments
This article will demonstrate usage of cordova-plugin-ble-central with IONIC 4. i.e. Mobile application connectivity with BlueTooth Low Energy Devices.

Before we start I assume that you already have ionic4 blank project working.

When you run ionic server command following screen should open in browser
ionic4 ble example code
Ionic4 BLE (Bluetooth Low energy sample/example code)

On command line or in visual studio terminal use following commands to install BLE  Ionic plugin


$ ionic cordova plugin add cordova-plugin-ble-central
$ npm install @ionic-native/ble
Above commands will add required cordova plugin and ionic4 wrapper for Bluetooth low energy devices communication. I am using default Home page to display list of available BLE Devices, on TAP of device it will be redirected to details page for further operations. We shall add following line of code to import BLE Home.page.ts file looks as follows


import { BLE } from '@ionic-native/ble/ngx';
import { Component, NgZone } from '@angular/core';
import { NavController, ToastController } from '@ionic/angular';


@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  constructor(
    public navCtrl: NavController,
    private toastCtrl: ToastController,
    private ble: BLE,
    private ngZone: NgZone
  ) {}

}


After this make sure BLE provider is added in app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

import { BLE } from '@ionic-native/ble/ngx';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
  providers: [
    StatusBar,
    SplashScreen, BLE,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}



Now we shall add following functions for Bluetooth low energy (BLE) device discovery and listing BLE devices.

  • scan - scan for ble devices for 5 seconds.
  • onDeviceDiscovered - this function will execute if any BLE device is discovered.
  • scanError - this function will be called if any error occurs in scan function
  • setStatus - simple function to set message 
Above functions we are adding in home.page.ts file. Location setting should be on while scanning devices, else you will see error message


scan() {
    this.setStatus("Scanning for Bluetooth LE Devices");
    this.devices = []; // clear list

    this.ble.scan([], 5).subscribe(
      device => this.onDeviceDiscovered(device),
      error => this.scanError(error)
    );

    setTimeout(this.setStatus.bind(this), 5000, "Scan complete");
  }

  onDeviceDiscovered(device) {
    console.log("Discovered " + JSON.stringify(device, null, 2));
    this.ngZone.run(() => {
      this.devices.push(device);
    });
  }

  // If location permission is denied, you'll end up here
  async scanError(error) {
    this.setStatus("Error " + error);
    let toast = await this.toastCtrl.create({
      message: "Error scanning for Bluetooth low energy devices",
      position: "middle",
      duration: 5000
    });
    toast.present();
  }

  setStatus(message) {
    console.log(message);
    this.ngZone.run(() => {
      this.statusMessage = message;
    });
  }


Please check HTML of home.page.html

<ion-header>
  <ion-toolbar>
    <ion-title>
      BLE Connect
    </ion-title>
    <ion-buttons slot="end">
      <ion-button click="" scan="">
        Scan
      </ion-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list> 
    <ion-item click="" device="" deviceselected=""
 ngfor="let device of devices">
      <ion-label>
      <h2>
{{ device.name || 'Unnamed' }}</h2>
{{ device.id }}
     RSSI: {{ device.rssi }}


      </ion-label> 
    </ion-item>
   
   </ion-list> 
</ion-content>

<ion-footer>
  <ion-toolbar>
    <ion-item>
    <ion-label>{{ statusMessage }}</ion-label>
    </ion-item>
  </ion-toolbar>
</ion-footer>

 


Now build app using following command
ionic cordova build android 

This will create an APK file which will list BLE devices after scan. You can click on scan button or can add scan() function in ionViewDidEnter()


ionViewDidEnter() {
    console.log('ionViewDidEnter');
    this.scan();
  }



Now we are able to build Bluetooth low energy device listing app in ionic4

Mobile application connectivity with BlueTooth Low Energy Devices


In next Article ionic 4 bluetooth low energy - sample code - Connect to BLE Devices we shall connect to BLE devices.

Share Share Tweet Share

12 thoughts on "ionic 4 bluetooth low energy - sample code - List BLE Devices"

avatar

Hi there. I'm getting the following error on Build. Hoping you could help. Thanks

ERROR in src/app/home/home.page.ts:42:7 - error TS1005: ';' expected.

42 async scanError(error)

avatar

unless you share code, I cannot help you.
Please share code snippet for same.

avatar

Here are the versions that I used. I have installed the latest ionic framework and an older version (4.11.0) which is about the current version when you posted this on your blog.

D:\PROJECTS\ME205>npm -v
6.14.8

D:\PROJECTS\ME205>node -v
v14.15.0

D:\PROJECTS\ME205>ionic cordova --version
4.11.0

D:\PROJECTS\ME205>ionic -v
IONIC CLI 4.11.0

D:\PROJECTS\ME205>tsc -v
Version 4.0.5

D:\PROJECTS\ME205>where tsc
C:\Users\~user\AppData\Roaming\npm\tsc
C:\Users\~user\AppData\Roaming\npm\tsc.cmd

avatar

package.json

{
"name": "ME205",
"version": "0.0.1",
"author": "Ionic Framework",
"homepage": "https://ionicframework.com/",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/common": "~10.0.0",
"@angular/core": "~10.0.0",
"@angular/forms": "~10.0.0",
"@angular/platform-browser": "~10.0.0",
"@angular/platform-browser-dynamic": "~10.0.0",
"@angular/router": "~10.0.0",
"@ionic-native/ble": "^5.29.0",
"@ionic-native/core": "^5.0.0",
"@ionic-native/splash-screen": "^5.0.0",
"@ionic-native/status-bar": "^5.0.0",
"@ionic/angular": "^5.0.0",
"cordova-android": "9.0.0",
"cordova-ios": "6.1.1",
"cordova-plugin-ble-central": "1.3.1",
"rxjs": "~6.5.5",
"tslib": "^2.0.0",
"zone.js": "~0.10.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.1002.0",
"@angular/cli": "~10.0.5",
"@angular/compiler": "~10.0.0",
"@angular/compiler-cli": "~10.0.0",
"@angular/language-service": "~10.0.0",
"@ionic/angular-toolkit": "^2.3.0",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"cordova-plugin-device": "^2.0.2",
"cordova-plugin-ionic-keyboard": "^2.2.0",
"cordova-plugin-ionic-webview": "^4.2.1",
"cordova-plugin-splashscreen": "^5.0.2",
"cordova-plugin-statusbar": "^2.4.2",
"cordova-plugin-whitelist": "^1.3.3",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~3.3.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~3.9.7"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-plugin-ble-central": {},
"cordova-plugin-whitelist": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
"cordova-plugin-ionic-keyboard": {}
},
"platforms": [
"android",
"ios"
]
}
}

avatar

I coded the home.page.html, app.module.ts, and home.page.ts exactly the way you coded it. Below is what I get on Ionic Serve cmd. There is an error on the async scanError function. The local host page just shows 'Cannot GET /'.

> ng run app:serve --host=0.0.0.0 --port=8100
[ng] WARNING: This is a simple server for use in testing or debugging Angular applications
[ng] locally. It hasn't been reviewed for security issues.
[ng] Binding this server to an open connection can result in compromising your application or
[ng] computer. Using a different host than the one passed to the "--host" flag might result in
[ng] websocket connection issues. You might need to use "--disableHostCheck" if that's the
[ng] case.
[ng] chunk {main} main.js, main.js.map (main) 1.75 kB [initial] [rendered]
[ng] chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 110 kB [initial] [rendered]
[ng] chunk {runtime} runtime.js, runtime.js.map (runtime) 6.15 kB [entry] [rendered]
[ng] chunk {styles} styles.js, styles.js.map (styles) 93 kB [initial] [rendered]
[ng] chunk {vendor} vendor.js, vendor.js.map (vendor) 339 kB [initial] [rendered]
[ng] Date: 2020-11-10T12:22:00.286Z - Hash: 2e7e90df1b0acd1b4e15 - Time: 3045ms
[ng] ERROR in src/app/home/home.page.ts:43:7 - error TS1005: ';' expected.
[ng] 43 async scanError(error)
[ng] ~~~~~~~~~

avatar

And this is what I get on build android.

D:\PROJECTS\ME205>ionic cordova build android
√ Creating .\www directory for you - done!
> ng run app:ionic-cordova-build --platform=android

ERROR in src/app/home/home.page.ts:43:7 - error TS1005: ';' expected.

43 async scanError(error)
~~~~~~~~~

[ERROR] An error occurred while running subprocess ng.

ng run app:ionic-cordova-build --platform=android exited with exit code 1.

Re-running this command with the --verbose flag may provide more information.

avatar

check this link https://stackoverflow.com/questions/46398916/typescript-error-ts1005-expected-ii

This comment has been removed by the author. - Deleted
avatar

this seems more of a versioning issue.

avatar

Hi, statusMessage: string; is missing in the home.page.js file
In the other guide you put statusMessage: string;
Anyway thank you so much I am following your guide.

avatar

I coded exactly as you did, but ot able to see name list of ble devices, only getting blank page. can you help? i added missing declarations of devices & statusMessege

avatar

Hi I can help, share your email.

LEAVE A REPLY