![](/img/trans.png)
[英]How to set the name of BLE peripheral in iOS using Core Bluetooth
[英]Incorrect BLE Peripheral Name with iOS
我正在編寫一個 iOS 應用程序來與 BLE 設備進行通信。 設備可以在連接之間更改名稱(不是在 BLE 連接期間),但 iOS 拒絕更改設備名稱。
例如:當設備名稱為 SadName 時,我可以連接到設備。 我斷開它,關閉應用程序等並將設備的名稱更改為HappyName。 但是,當我掃描設備時,iOS 仍然將外圍設備名稱顯示為 SadName。
如果我調試應用程序並查看:
(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
peripheral.name 的值是 SadName 所以我不認為這是我在代碼中錯誤解釋的東西。 我應該提到,當我掃描設備時,我的代碼是:
[self.CM scanForPeripheralsWithServices:nil options:0]; // Start scanning
我猜這只是因為設備 UUID 是相同的,所以 iOS 將它從它的緩存設備列表中拉出來,但我想覆蓋它。
想法? 抱歉,我是 iOS 新手。 干杯 - MSchmidtbauer
iOS SDK 的 CoreBluetooth API 沒有提供強制刷新外設名稱的方法。
當前在 BLEdevice 中的設備名稱更改時,在 iOS 中使用peripheral.name 是不可行的。
Apple 建議通過指定傳遞給 scanForPeripheralsWithServices 的 CBUUID 對象列表(包含一個或多個服務 UUID)來掃描特定設備:
NSArray *services = @[[CBUUID UUIDWithString: @"2456e1b9-26e2-8f83-e744-f34f01e9d701"] ]; // change to your service UUID!
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[self.manager scanForPeripheralsWithServices:services options:dictionary];
這減少了 didDiscoverPeripheral 的調用次數。 不要只是將 nil 傳遞給 scanForPeripheralsWithServices。 它還允許您的應用程序在處於后台狀態時掃描外圍設備。
如果您正在尋找一種在建立連接之前廣播可用動態信息的方法,您可以使用Advertise 或 Scan Response Data 。 外設可以配置為廣播稱為本地名稱和制造商特定數據的條目。 此數據在 didDiscoverPeripheral 中可用:
- (void)centralManager: (CBCentralManager *)central
didDiscoverPeripheral: (CBPeripheral *)peripheral
advertisementData: (NSDictionary *)advertisementData
RSSI: (NSNumber *)RSSI {
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
NSData *manufacturerData = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey];
NSLog(@"Local: name: %@", localName);
NSLog(@"Manufact. Data: %@", [manufacturerData description]);
}
本地名稱是一個 NSString ,因此在此字段中僅在 BLE 設備上寫入可打印字符。 制造商數據是一個 NSData ,它可以包含任何字節值,所以你甚至可以在這里擁有二進制數據。
根據您使用的 BLE 設備,本地名稱和制造商特定數據的長度是有限的。
在我的 BLE 設備上,我可以發送 128 位服務 UUID 和一個 8 字符的本地名稱以及廣告數據。 制造商特定數據進入掃描響應數據並且可以是 29 字節長。
使用 Adv./Scan Response Data 的好處是,它可以在此 BLE 設備上更改而無需重啟。
建議:
你的猜測是正確的。
這是因為core-blutetooth
緩存。
通常“不支持”更改 BLE 設備上的名稱/服務/特性。 所有這些參數都被緩存。
有兩種方法可以解決這個問題:
或者檢查您的 BLE 設備的廣告數據。 它可能有一個name
屬性,每次 BLE 設備廣告數據時都應該刷新該屬性(廣告數據不會被緩存)。
CBPeripheralDelegate
協議包含一個方法...
- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral NS_AVAILABLE(NA, 6_0);
...這是為此目的而制作的。
編輯 - 剛剛意識到上面接受的答案的第二部分具有相同的解決方案:-(我應該更仔細地閱讀。無論如何我都會把這個答案留在這里,因為它包含了 RoboVM 代碼。
我找到了解決這個問題的方法。 添加 GATT 服務更改特性不起作用,直接從設備名稱特性 2A00 讀取設備名稱也不起作用,因為 iOS 隱藏了通用訪問服務。 但是,如果外圍設備在廣告數據包中包含其本地名稱,則可以使用檢索鍵CBAdvertisementDataLocalNameKey
從掃描結果上提供的廣告數據字典中獲得該CBAdvertisementDataLocalNameKey
。 我將其復制到我的 BLE 設備包裝器中,並使用它而不是 CBPeripheral 提供的名稱。 RoboVM 的 Java 示例代碼如下。 OBJC 或 Swift 等價物很簡單。
@Override
public void didDiscoverPeripheral(CBCentralManager cbCentralManager, CBPeripheral cbPeripheral, CBAdvertisementData cbAdvertisementData, NSNumber rssi) {
NSData manufacturerData = cbAdvertisementData.getManufacturerData();
byte[] data = null;
if(manufacturerData != null)
data = manufacturerData.getBytes();
IosBleDevice bleDevice = new IosBleDevice(cbPeripheral);
String name = cbAdvertisementData.getLocalName();
if(name != null && !name.equals(cbPeripheral.getName())) {
CJLog.logMsg("Set local name to %s (was %s)", name, cbPeripheral.getName());
bleDevice.setName(name);
}
deviceList.put(bleDevice.getAddress(), bleDevice);
if(!iosBlueMaxService.getSubscriber().isDisposed()) {
BleScanResult bleScanResult = new IosBleScanResult(bleDevice,
cbAdvertisementData.isConnectable(),
data);
bleScanResult.setRssi(rssi.intValue());
iosBlueMaxService.getSubscriber().onNext(bleScanResult);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.