我正在做一个项目,我必须连接(不是绑定)到带有按钮的蓝牙设备。 这些实现适用于 Android,但无法连接我用于测试的 iPhone SE(iOS 16.4)。
我的开发环境如下: 工作站:Windows 10 上的 Visual Studio Code NPM 版本:9.5.0 离子版本:5.4.16 节点版本:18.15.0
我正在使用以下插件来处理蓝牙 LE 连接: https://github.com/capacitor-community/bluetooth-le#requestbledeviceoptions
我使用 Android Studio 直接从我的工作站传输到我们的测试 Android 手机 我通过 Git 将代码传输到 Macbook 以将其传输到 xCode 和我们的测试 iPhone
我的 Ionic 服务中的连接功能如下所示:
/**
* Connect to iTag device and start listening for notifications
* @param deviceID
* @param bondDevice
* @param notificationCallback
* @param successCallback
* @param errorCallback
* @param disconnectCallback
* @param stateChangeCallback
*/
public async itagConnect(
deviceID: string = "",
bondDevice = false,
successCallback: CallableFunction = this.onSuccess,
errorCallback: CallableFunction = this.onError,
disconnectCallback: CallableFunction = this.onDisconnect,
stateChangeCallback: CallableFunction = this.onStateChange
): Promise<void> {
try {
if (this.bluetoothConnectedDevice.length > 0) {
console.log("Already connected: ", this.bluetoothConnectedDevice);
errorCallback("Already connected to a device");
return;
}
// Connect device
console.log("Connecting to device", deviceID);
this.onStatusUpdate("Connecting to device \""+deviceID+"\"");
await BleClient.connect(
deviceID,
() => {
disconnectCallback();
},
{timeout: 10000}
).then(
() => {
//Keep bluetooth connection alive by reading device battery level
console.log("Start monitoring battery level");
this.onStatusUpdate("Start monitoring battery level");
this.batteryMonitor = setInterval(() => {
if (this.bluetoothConnectedDevice.length == 0 || this.bluetoothIsScanning) {
clearInterval(this.batteryMonitor);
} else {
this.ReadBatteryLevel(deviceID);
}
}, 1000);
console.log("Connection successfull");
this.onStatusUpdate("Connection successfull");
}
)
//Bond/pair device to phone (Android only!)
if (bondDevice) {
console.log("Bonding with device");
this.onStatusUpdate("Bonding with device");
if (!BleClient.isBonded(deviceID)) {
BleClient.createBond(deviceID);
}
} else {
console.log("Bonding is disabled");
this.onStatusUpdate("Bonding is disabled");
}
// Monitor for bluetooth state change
console.log("Start bluetooth state monitoring");
this.onStatusUpdate("Start bluetooth state monitoring");
BleClient.startEnabledNotifications(
(value: boolean) => {
stateChangeCallback(value);
}
)
// If no errors, call success callback function
this.connected = true;
this.bluetoothScanResults = [];
successCallback()
} catch (error) {
// BLE connecton failed
console.log("iTAG connect error: ", error);
errorCallback("iTAG connect error: "+error.name+" - "+error.message)
}
}
我从 xCode 得到的调试反馈是这样的:
⚡️ Native -> BluetoothLe initialize 28948423
⚡️ BluetoothLe - Resolve initialize BLE powered on
⚡️ TO JS undefined
⚡️ To Native -> BluetoothLe getConnectedDevices 28948424
⚡️ TO JS {"devices":[]}
⚡️ To Native -> BluetoothLe
⚡️ [log] - BLE STATUS: Attempting to connect to device "59353DDC-DACC-D596-F0EC-CFB22B9000DC"
removeListener 28948425
⚡️ [log] - BLE STATUS: Connecting to device "59353DDC-DACC-D596-F0EC-CFB22B9000DC"
⚡️ To Native -> BluetoothLe addListener 28948426
⚡️ To Native -> BluetoothLe connect 28948427
⚡️ BluetoothLe - Connecting to peripheral <CBPeripheral: 0x280e27740, identifier = 59353DDC-DACC-D596-F0EC-CFB22B9000DC, name = iTAG , mtu = 23, state = disconnecting>
⚡️ BluetoothLe - Reject connect Connection timeout
ERROR MESSAGE: {"errorMessage":"Connection timeout","message":"Connection timeout"}
⚡️ [error] - {"errorMessage":"Connection timeout","message":"Connection timeout"}
⚡️ [log] - BLE STATUS: ERROR! Error while connecting to device "iTAG coneect error: Error - Connection timeout"
⚡️ To Native -> BluetoothLe initialize 28948428
⚡️ BluetoothLe - Resolve initialize BLE powered on
⚡️ TO JS undefined
⚡️ To Native -> BluetoothLe getConnectedDevices 28948429
⚡️ TO JS {"devices":[]}
2023-05-17 10:31:05.232793+0200 App[634:18510] [Snapshotting] Snapshotting a view (0x10182ee00, UIKeyboardImpl) that is not in a visible window requires afterScreenUpdates:YES.
我浏览了有关开发 iPhone 蓝牙应用程序的杂项帖子,并进行了以下操作:
On iOS, add the NSBluetoothAlwaysUsageDescription to Info.plist, otherwise the app will crash when trying to use Bluetooth (see here).
[https://developer.apple.com/documentation/corebluetooth](https://stackoverflow.com)
If the app needs to use Bluetooth while it is in the background, you also have to add bluetooth-central to UIBackgroundModes (for details see here).
[https://developer.apple.com/documentation/bundleresources/information_property_list/uibackgroundmodes](https://stackoverflow.com)
我测试了装有 iOS 15.7 的旧 iPhone 6S 和装有 iOS 16.4 的较新 iPhone SE,并更新了 MacBook 上的操作系统和 xCode 版本以匹配手机(S)
该应用程序应该能够连接到 iTAG 龅牙设备并监听在 Android 上运行的内置按钮服务,但在我能够进行任何形式的读取以保持连接有效之前,在 iPhone 上初始连接失败.