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
On command line or in visual studio terminal use following commands to install BLE Ionic plugin
After this make sure BLE provider is added in app.module.ts
Now we shall add following functions for Bluetooth low energy (BLE) device discovery and listing BLE devices.
Please check HTML of home.page.html
Now build app using following command
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()
Now we are able to build Bluetooth low energy device listing app in ionic4
In next Article ionic 4 bluetooth low energy - sample code - Connect to BLE Devices we shall connect to BLE 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 (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/bleAbove 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
In next Article ionic 4 bluetooth low energy - sample code - Connect to BLE Devices we shall connect to BLE devices.
12 thoughts on "ionic 4 bluetooth low energy - sample code - List BLE Devices"
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)
unless you share code, I cannot help you.
Please share code snippet for same.
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
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"
]
}
}
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] ~~~~~~~~~
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.
check this link https://stackoverflow.com/questions/46398916/typescript-error-ts1005-expected-ii
this seems more of a versioning issue.
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.
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
Hi I can help, share your email.