Ionic 3中如何通过蓝牙读取条码扫描器数据?
解决Ionic 3 BluetoothSerial无法实时显示条码扫描数据的问题
看起来你已经搞定了蓝牙连接的部分,这很棒!但扫描数据没法实时显示,问题出在数据监听的方式和数据绑定的逻辑上,我帮你梳理一下:
核心问题分析
- 单次读取无法监听实时数据:你现在用
bluetoothSerial.read()是一次性读取当前可用的数据,但条码扫描器是每次扫描才发送新数据,这种方式没法捕捉后续的扫描结果。 - 数据绑定逻辑搞反了:页面上的输入框绑定的是
inputData,但你代码里写的是this.data=this.inputData,这等于把空值赋值给data,完全反了。 - 没有持续监听串口数据流:BluetoothSerial提供了
subscribe()方法,可以持续监听蓝牙串口的数据,这才是实时获取扫描数据的正确姿势。
修改后的代码实现
1. 更新HomePage的.ts文件
我调整了连接后的逻辑,用subscribe()持续监听数据,同时修正了数据绑定的问题:
import { Component } from '@angular/core'; import { BluetoothSerial } from '@ionic-native/bluetooth-serial'; import { AlertController } from 'ionic-angular'; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { unpairedDevices: any; pairedDevices: any; gettingDevices: Boolean; inputData: string = ""; // 页面绑定的变量 constructor(private bluetoothSerial: BluetoothSerial, private alertCtrl: AlertController) { bluetoothSerial.enable(); } startScanning() { this.pairedDevices = null; this.unpairedDevices = null; this.gettingDevices = true; this.bluetoothSerial.discoverUnpaired().then((success) => { this.unpairedDevices = success; this.gettingDevices = false; }, (err) => { console.log(err); }); this.bluetoothSerial.list().then((success) => { this.pairedDevices = success; }, (err) => { console.log(err); }); } // 处理成功接收数据的回调 onDataReceived(data: string) { console.log("扫描到的数据:", data); // 把扫描到的数据赋值给inputData,页面会自动更新 this.inputData = data.trim(); // 去掉可能的换行符 } onConnectionError(error: any) { alert("连接出错: " + JSON.stringify(error)); console.log(error); } selectDevice(address: any) { let alert = this.alertCtrl.create({ title: 'Connect', message: 'Do you want to connect with this device?', buttons: [ { text: 'Cancel', role: 'cancel', handler: () => { console.log('Cancel clicked'); } }, { text: 'Connect', handler: () => { // 连接设备后,立即订阅数据流 this.bluetoothSerial.connect(address) .subscribe( (data) => this.onDataReceived(data), // 实时接收数据 (error) => this.onConnectionError(error) ); } } ] }); alert.present(); } disconnect() { let alert = this.alertCtrl.create({ title: 'Disconnect?', message: 'Do you want to Disconnect?', buttons: [ { text: 'Cancel', role: 'cancel', handler: () => { console.log('Cancel clicked'); } }, { text: 'Disconnect', handler: () => { this.bluetoothSerial.disconnect(); this.inputData = ""; // 断开后清空显示 } } ] }); alert.present(); } }
2. 调整HomePage的.html文件
主要是修正输入框的绑定逻辑,确保显示的是inputData:
<ion-list padding> <button ion-button block (click)="startScanning()">Scan Devices</button> <ion-list-header>Paired Devices</ion-list-header> <ion-item *ngFor="let device of pairedDevices" (click)="selectDevice(device.address)"> {{device.name}} </ion-item> <button ion-button block (click)="disconnect()" *ngIf="inputData">Disconnect</button> <ion-list-header>Available Devices</ion-list-header> <ion-item *ngFor='let device of unpairedDevices' (click)="selectDevice(device.address)"> {{device.name}} </ion-item> <ion-spinner name="crescent" *ngIf="gettingDevices"></ion-spinner> <ion-item> <ion-label stacked>Scanned Data</ion-label> <ion-input type="text" readonly [(ngModel)]="inputData"></ion-input> </ion-item> </ion-list>
关键修改点说明
- 用subscribe监听数据流:
bluetoothSerial.connect(address).subscribe(...)会持续监听蓝牙串口的数据,每次扫描器发送数据时,都会触发onDataReceived回调。 - 修正数据绑定:把扫描到的数据直接赋值给
inputData,因为页面上的ion-input用[(ngModel)]="inputData"双向绑定,赋值后页面会自动更新。 - 优化用户体验:断开连接时清空显示内容,并且只有连接后才显示断开按钮。
- 处理多余字符:用
trim()去掉扫描数据可能带的换行或空格,确保显示干净的条码内容。
这样修改后,你扫描条码时,数据应该就能实时显示在页面上了!
内容的提问来源于stack exchange,提问作者Mohd Saif khan
相关产品推荐
相关产品推荐

