所以我有一个iOS应用程序,它宣传为BLE外围设备并使用CBPeripheralManager和CBCentralManager查看其他外围设备,当我将这些样本作为iOS到iOS运行时,一切正常。我在Android上还有另一个应用程序可以做同样的事情,Android到Android也可以看到对方都很好。这个变得凌乱的地方是Android可以看到iOS设备的广告,但iOS无法看到Android设备的广告。以前有人遇到过这种情况吗?我的Android广告代码如下所示:
private void advertise( String someString ) {
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && BluetoothAdapter.getDefaultAdapter().isMultipleAdvertisementSupported() ) {
BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
AdvertiseSettings settings = new AdvertiseSettings.Builder()
.setAdvertiseMode( AdvertiseSettings.ADVERTISE_MODE_BALANCED )
.setTxPowerLevel( AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM )
.setConnectable( false )
.build();
UUID uuid = UUID.fromString( mUUID );
ParcelUuid pUuid = new ParcelUuid( uuid );
AdvertiseData data = new AdvertiseData.Builder()
.setIncludeDeviceName( true )
.setIncludeTxPowerLevel( true )
.addServiceUuid( pUuid )
.addServiceData( pUuid, someString.getBytes( Charset.forName("UTF-8") ) )
.build();
//Using a wrapper class for the callback for backwards compatibility issues
advertiser.startAdvertising(settings, data, AdvertisingCallbackCreator.getAdvertiseCallback());
} else {
if( Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ) {
DLog.v( "Device requires Lollipop or higher to broadcast over bluetooth" );
} else {
DLog.v( "Device must support multiple advertising in order to broadcast over bluetooth. http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#isMultipleAdvertisementSupported() ");
}
}
}
我的iOS应用非常简单,一个目标是扫描仪,另一个是广告客户。在查看Android时遇到问题的扫描仪在ViewController类中看起来像这样:
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) CBCentralManager* pMgr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initWithUUID:nil];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)peripheral{
if (peripheral.state == CBCentralManagerStatePoweredOn) {
[self startDiscovery];
}
}
-(void)initWithUUID:(CBUUID*) uuid{
if( self ) {
_serviceUUID = uuid;
_pMgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
}
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog( @"%@", advertisementData );
}
-(void) startDiscovery {
NSArray *array = @[[CBUUID UUIDWithString:@"6098FDEF-B82C-43F1-8BFB-18757743BA10"]];
[_pMgr scanForPeripheralsWithServices:array options:nil];
}
@end
Android和iOS都可以看到我的广告客户:
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) CBPeripheralManager* pMgr;
@property (strong, nonatomic) CBMutableService* shareService;
@property (strong, nonatomic) CBMutableCharacteristic* notificationCharacteristic;
@property (strong, nonatomic) NSMutableArray *queuedWrites;
@property (strong, nonatomic) NSLock *queuedWritesLock;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initWithUUID:[CBUUID UUIDWithString:@"6098FDEF-B82C-43F1-8BFB-18757743BA10"]];
[self startAdvertising];
}
-(void) initWithUUID:(CBUUID*) uuid{
if( self ) {
_serviceUUID = uuid;
_pMgr = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
self.bkvsName = [[UIDevice currentDevice] name];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) startAdvertising {
if ([_pMgr state] == CBPeripheralManagerStatePoweredOn) {
NSDictionary* adDictionary = @{ CBAdvertisementDataLocalNameKey :
[NSString stringWithFormat:@"BKV %@", _bkvsName ],
CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:@"6098FDEF-B82C-43F1-8BFB-18757743BA10"]]};
[_pMgr startAdvertising:adDictionary];
}
}
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
if (peripheral.state == CBPeripheralManagerStatePoweredOn) {
_shareService = [[CBMutableService alloc] initWithType:_serviceUUID primary:YES];
_notifyUUID = [CBUUID UUIDWithString:@"F098FDEF-B82C-43F1-8BFB-18757743BA10"];
_notificationCharacteristic = [[CBMutableCharacteristic alloc] initWithType:_notifyUUID
properties:CBCharacteristicPropertyNotify
value:nil
permissions:CBAttributePermissionsReadable];
[_shareService setCharacteristics:@[_notificationCharacteristic]];
[_pMgr addService:_shareService];
[self startAdvertising];
}
}
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error {
if (error) {
NSLog(@"Error: %@",error);
}
}
-(void) stopAdvertising{
[_pMgr stopAdvertising];
}
@end
如果有人对可能出错的地方有一些指示,那就太棒了。我试图让iOS代码变得非常简单,因为我刚开始学习它。
编辑:
来自广告iOS设备的原始数据包:
2015-09-22 21:30:18.518 BLEScanner[724:42204] {
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = "BKV EV59'\U2019\U2018`s iphone ";
kCBAdvDataServiceUUIDs = (
"6098FDEF-B82C-43F1-8BFB-18757743BA10"
);
}
此外,当在scanForPeripheralsWithServices中使用nil而不是数组时,仍然看不到Android设备。扫描仪确实拿起了我附近的另一个蓝牙设备,这个设备处于广告模式(支持蓝牙的玩具,而不是手机)。
虽然我不认为这会起作用,但我正在测试的设备是M预览3上的Nexus 9,5.1.1上的Nexus 6和两个iPod Touch(最近运行iOS 8.3和8.4的型号)