Непрерывное сканирование iOS CoreBluetooth Central Manager?

Спецификация Bluetooth с низким энергопотреблением мало говорит о том, могут ли периферийные устройства подключаться к более чем одному центральному устройству одновременно, но мой опыт тестирования говорит мне, что это невозможно.

Поскольку моему приложению требуются несобственнические отношения с периферийными устройствами (т. е. никаких соединений, которые блокировали бы другие) и необходимо постоянно обновлять их значения RSSI, я ищу способ непрерывного сканирования периферийных устройств и захвата их значений RSSI.

Метод scanForPeripheralsWithServices выполняет сканирование в течение определенного интервала, а затем останавливается. Я считаю, что лучше всего сканировать в течение 3 секунд за раз, останавливать сканирование, ждать (несколько секунд), а затем повторно запускать сканирование. Повторить.

Может ли кто-нибудь указать на лучший способ сделать это? Например, настройка периферийного устройства для подключения к более чем одному центральному?


person Jonathan    schedule 16.05.2013    source источник


Ответы (3)


Периферийное устройство не может подключаться более чем к одному центральному устройству. Но если вам нужно просто захватить RSSI, вам даже не нужно подключаться. Сканирование устройств может получить RSSI с помощью этой функции:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
person Aboelseoud    schedule 16.05.2013
comment
Да, но мне нужно постоянно получать обновленный RSSI. Мои выводы заключаются в том, что после того, как Central Manager обнаружил и повторно обнаружил периферийное устройство несколько раз, он перестает его обнаруживать (кажется, около 3 секунд), даже если сканирование продолжается. Что мне осталось, так это необходимость повторно инициировать сканирование несколько раз, чтобы попытаться получить обновленные значения RSSI. - person Jonathan; 16.05.2013
comment
Да, вы можете повторно инициировать сканирование внутри функции didDiscoverPeripheral, и тем самым вы всегда будете быстро получать RSSI. - person Aboelseoud; 17.05.2013
comment
Спасибо. Это работает. В целях экономии энергии я фактически останавливаю сканирование после 100 мс, а затем делаю 100-мс пакет каждую секунду или около того. Прекрасно работает. - person Jonathan; 20.05.2013
comment
Не могли бы вы указать документацию, в которой периферийное устройство не может подключаться более чем к одному центральному? В CBCentralManagerDelegate есть функция с именем - (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals, где периферия - это массив. - person Jon; 24.10.2013
comment
Привет, Джонатан, не могли бы вы опубликовать свой код фрагментов, чтобы сделать это? - person megabri; 27.02.2015

Что касается предыдущего ответа, если вас интересует только RSSI, вы можете просто получить его в методе делегата:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

Кстати, по умолчанию CBCentralManager вызывает этот метод только один раз. Если вам нужно, чтобы этот обратный вызов вызывался каждый раз, когда CBCentralManager получает рекламный пакет, вам нужно инициировать сканирование с опцией CBCentralManagerScanOptionAllowDuplicatesKey, установленной на YES:

NSDictionary *scanningOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey: @YES};
[centralManager scanForPeripheralsWithServices:nil options:scanningOptions];

Имейте в виду, что Apple не рекомендует использовать эту опцию, если в этом нет крайней необходимости.

См.: Библиотека для разработчиков iOS — рекомендации по взаимодействию с удаленным периферийным устройством

person Dario Fiumicello    schedule 31.08.2015

Я решил эту проблему с помощью этого кода, в основном просто перезапуская сканирование каждый раз, когда обрабатывается реклама. Я столкнулся с той же проблемой, когда экземпляр CBCentralManager переставал слушать периферийное устройство.

(Установка CBCentralManagerScanOptionAllowDuplicatesKey на @YES не полностью решила проблему для меня.)

Предполагая, что класс реализует CBCentralManagerDelegate:

- (id) init {
    self.central = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
    [self initScan];
}

- (void) initScan {
    [self.central stopScan];
    [self.central scanForPeripheralsWithServices:nil
                                         options:[NSDictionary dictionaryWithObjectsAndKeys:@NO, CBCentralManagerScanOptionAllowDuplicatesKey, nil]];
}

- (void) centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI {

    //
    // Do stuff here
    //

    [self initScan];
}
person eskimwier    schedule 22.11.2016
comment
Это работает. В итоге я также установил задержку для дросселирования частоты сканирования. - person zumzum; 30.04.2020