gpt4 book ai didi

java - 通过 JNI 从 Java 使用 CoreBluetooth 时未调用 didDiscoverCharacteristics

转载 作者:行者123 更新时间:2023-11-28 05:41:24 26 4
gpt4 key购买 nike

我正在为 MacOS 上的低功耗蓝牙实现一个 Java 接口(interface)。我们想通过 JNI 调用 CoreBluetooth API。我能够扫描设备并填充服务,但我无法使特征起作用,因为 didDiscoverCharacteristics 似乎没有被调用。

当作为可执行文件运行时,可以扫描设备、连接设备,并使用 C++ 填充和打印设备的服务/特征。然后应用程序被构建为一个动态库,并且可以用 Java 加载。在 Java 中,设备被扫描并成功连接,并且可以发现其服务。但是从 Java 调用时永远不会发现特征。

这里是服务人口的流动,为了清楚起见,省略了一些多余的部分:

C++:BluetoothCentralNative.cpp

// tell "macable bridge" to populate services/characteristics
macableBridge.populateServices(name, UUID);
// retreive the discovered services (with characteristics populated)
vector<vector<string>> serviceData = macableBridge.getDiscoveredServices();

Objective-C++:MacableBridge.mm

void MacableBridge::populateServices(string name, string UUID) {
NSString* nameString = [NSString stringWithCString:name.c_str() encoding:NSUTF8StringEncoding];
NSString* uuidString = [NSString stringWithCString:UUID.c_str() encoding:NSUTF8StringEncoding];
CBPeripheral* foundPeripheral = [macable findPeripheral:nameString deviceUUID:uuidString];
[macable connectToDevice:foundPeripheral];
[macable populateServices:foundPeripheral];
}

目标-C:Macable.m

- (void) populateServices:(CBPeripheral *)device {
[_swift populateServicesWithDevice:device];
// sleep needs to be here to discover characteristics successfully as executable
// but when we sleep, thread seems to die when calling this library from java
sleep(1);
// more on retrieval of populated services later
}

Swiftable.swift

@objc public func populateServices(device: CBPeripheral) {
device.discoverServices(nil);
}

PeripheralDelegate.swift

// invoked when the peripheral's available services are discovered
public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
print("\nServices discovered!\n")
//middleman.gotServices(peripheral.services) (more on this later)
for service in peripheral.services! {
peripheral.discoverCharacteristics(nil, for: service)
}
}

// invoked when characteristics of a specified service are discovered
public func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
print("Discovered characteristics for service: \(service)")
//middleman.gotCharacteristics(service)
}

仅当 Swiftable 发现所有服务和特征时,我才尝试在 Macable 中设置一组 CBServices。我尝试在 Macable 和 Swiftable 之间实现一个“中间人”,每次 Swiftable 的 PeripheralDelegate 发现服务或服务的特征时,它都会更新中间人的服务列表。同样,一切都作为可执行文件工作,但在 Java 中使用 .dylib 时则不然。

我想知道如何强制任何 C++、Obj-C++ 或 Swift 层等待 Swift 调用“didDiscoverCharacteristics”函数。如果我使用 while 循环来等待特征,主线程就会被阻塞,我的程序将永远运行,等待从未发生过的特征发现。如果我强制我的程序 hibernate ,则在 Java 中使用 .dylib 时线程似乎被放弃了。

在我看来,发现设备和服务人口的逻辑与等待特征发现的逻辑相同,但只有前两个工作正常。

基于此JS library ,我知道可以用非本地语言为 CoreBluetooth 实现 API。

更新:这是 Java 的问题。我们的应用程序使用 Java 8 与 JNI 对话。更新到 Java 9 完全解决了这个问题,无需在 Swift 方面进行任何更改。

最佳答案

当您未能保留对相关对象的引用时,CoreBluetooth 往往会以这种方式运行。确保在 BLE 对话的整个生命周期内保留对您感兴趣的外围设备、服务和特征的持久引用。

关于java - 通过 JNI 从 Java 使用 CoreBluetooth 时未调用 didDiscoverCharacteristics,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56601771/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com