2012-09-20 10 views
11

¿Por qué obtengo CBCentralManagerStateUnknown en un iPad 2 cuando uso este código simple?¿Qué causa CBCentralManagerStateUnknown en iOS?

- (BOOL)viewDidLoad { 

    bluetoothManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 

    if ([manager state] == CBCentralManagerStatePoweredOff) NSLog(@"CBCentralManagerStatePoweredOff"); 
    if ([manager state] == CBCentralManagerStatePoweredOn) NSLog(@"CBCentralManagerStatePoweredOn"); 
    if ([manager state] == CBCentralManagerStateResetting) NSLog(@"CBCentralManagerStateResetting"); 
    if ([manager state] == CBCentralManagerStateUnauthorized) NSLog(@"CBCentralManagerStateUnauthorized"); 
    if ([manager state] == CBCentralManagerStateUnknown) NSLog(@"CBCentralManagerStateUnknown"); 
    if ([manager state] == CBCentralManagerStateUnsupported) NSLog(@"CBCentralManagerStateUnsupported"); 

} 

no puedo averiguar qué CBCentralManagerStateUnknown medios. ¿Qué debo hacer? El Apple docs acaba de decir:

Estado desconocido, actualizar inminente.

Aparece esta respuesta con un dispositivo Bluetooth conectado, y también cuando Bluetooth está desactivado. si trato de ejecutar algo así como [manager retrieveConnectedPeripherals], también me sale este mensaje en la consola:

CoreBluetooth[WARNING] <CBConcreteCentralManager: ...> is not powered on 
+1

Significa que el estado es desconocido. En este caso, probablemente porque el hardware Bluetooth no se ha reiniciado aún. ¿Cuál es el problema? –

+0

No puedo llevarlo al estado 'CBCentralManagerStatePoweredOn' para que pueda hacer cualquier cosa. ¿Qué tengo que hacer para llevarlo a ese estado? – woz

+0

Estoy un poco confundido. Mencionó que "recibo esta respuesta con un dispositivo Bluetooth conectado", pero también indicó que no puede hacer nada. ¿Cómo se conecta el dispositivo en primer lugar? – yuklai

Respuesta

15

Sé por qué nunca se llama al delegado. Porque el objeto se borró de la memoria. Simplemente haga una fuerte propiedad

@property (strong, nonatomic) DiscoverBluetoothDevices *btDevices;

Y en init

@implementation DiscoverBluetoothDevices 
- (id) init 
{ 
    self = [super init]; 
    if(self) { 
     centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()]; 
     [centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @YES}]; 

    } 
    return self; 
} 

Y ahora se llama delegar correctamente.

+0

Intente cambiar el código de [self.manager scanForPeripheralsWithServices: [NSArray arrayWithObject: [CBUUID UUIDWithString: @ "180D"]] options: nil]; con NSDictionary * dictionary = [NSDictionary dictionaryWithObject: [NSNumber numberWithBool: YES] forKey: CBCentralManagerScanOptionAllowDuplicatesKey]; [self.manager scanForPeripheralsWithServices: opciones nulas: diccionario]; – york

+2

¿Por qué? Mi código está funcionando bien :) –

2

CBCentralManagerStateUnknown simplemente significa IOS ha iniciado el proceso BLE, pero no se ha completado la inicialización. Dale un momento, y el estado cambiará.

En general, le "dará un momento" al detectar un cambio de estado en un controlador delegado CBCentralManagerDelegate en lugar de mirarlo justo después de la llamada de inicialización. Va a poner en práctica

- (void) centralManagerDidUpdateState: (CBCentralManager *) central; 

Hay algunos buenos ejemplos que muestran esta, como Apple de heart rate monitor.

+3

Tengo un punto de interrupción en esa función, pero nunca se llama a la función. – woz

+0

Tengo el mismo problema centralManagerDidUpdateState que nunca se llama – Warewolf

+1

Dependiendo de lo que haya estado haciendo hasta este punto, una cosa que podría intentar es reiniciar su dispositivo iOS. He visto que iOS se confunde con los enlaces BLE en el pasado, generalmente cuando se usan varias aplicaciones para conectarse a un solo dispositivo. Reiniciar el dispositivo a menudo es lo único que parece aclarar el problema. – Mike

1

La respuesta real (la vieja pregunta que sé); Inicie un escaneo de periféricos, esto iniciará BT LE y sus delegados recibirán una llamada de vuelta. Mis Delegados y la información del estado no cambiaron hasta que hice esto.

a. Configure su cbcentralmanager como se detalla a continuación b. Tenga los delegados -central * en su código y en su archivo .h c. NSLog o tiene una etiqueta en la actualización de la pantalla con nuevo estado. Y éxito.

cManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 

[cManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @YES}]; 
+0

Esta respuesta es suficiente para poner esto en marcha. – d2burke

1

Necesita conservar la instancia CBCentralManager (ponerlo en un ivar o propiedad privada) y esperar a que se llame al delegado de cambio de estado. (El estado siempre es "desconocido" si lo comprueba inmediatamente después de crear el administrador. El estado real aparecerá momentáneamente en el método de delegado)

2

Si el estado central va a CBCentralManagerStateUnsupported (mientras que Bluetooth Low Energy es compatible con dispositivo) lo más probable es que la aplicación haya hecho algo malo con CoreBluetooth.

Compruebe los registros de iOS Bluetooth Diagnostic Logging.

Por ejemplo, si hace esto ...

_cm1 = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{ CBCentralManagerOptionRestoreIdentifierKey: @"not_unique" }]; _cm2 = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{ CBCentralManagerOptionRestoreIdentifierKey: @"not_unique" }];

... el estado del segundo centro se destinará a CBCentralManagerStateUnsupported.

0

En mi caso lo usamos AppDelegate como delegado para

CBCentralManagerDelegate 

y indirectional para

AVCaptureMetadataOutputObjectsDelegate. 

en un momento dado.

1) Tenga cuidado con los hilos. Utilice

dispatch_get_main_queue() 

o

[NSThread mainThread] 

para el trabajo con BLE.

2) Tenga cuidado al usar estos 2 delegados en 1 objeto. Porque el hardware es NOT thead y context save

Cuestiones relacionadas