好吧,我正在做一个有趣的项目,有一个障碍,我需要为我的iOS应用程序启用蓝牙音频支持。
我遇到的障碍是,我甚至不能开始获得连接的蓝牙音频设备的列表。尽管我的iPhone 5S可以识别我的耳机(确切地说,是一个3 - 4岁的LG HBM-230),并通过它播放音频来打电话,但当我查询这两个配件时,外部配件和CoreBluetooth都没有给我任何有用的东西。
我的代码基于我为CoreBluetooth和External Accessory框架找到的问题和答案。
当我的代码只是尝试“scanForPeripheralsWithServices:nil
”为 * 任何 * 蓝牙设备,其中设置->蓝牙说是可见的和连接,下面的代码只是没有来一个单一的打击以外的“CBCentralManagerStatePoweredOn
”消息在控制台。
而我的代码中的这一行(带有有效的EAAccessoryManager示例)
NSArray * connectedDevices = [self.eAAccessoryManager connectedAccessories];
也返回一个nil数组。
我能做错什么?
B.T.W.,I've made this code available as a GitHub project .
@implementation BluetoothManager
+ (BluetoothManager *)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _bluetoothMGR = nil;
dispatch_once(&pred, ^{
_bluetoothMGR = [[BluetoothManager alloc] init];
});
return _bluetoothMGR;
}
- (id)init
{
self = [super init];
if(self)
{
dispatch_queue_t centralQueue = dispatch_queue_create("com.yo.mycentral", DISPATCH_QUEUE_SERIAL);
// whether we try this on a queue of "nil" (the main queue) or this separate thread, still not getting results
self.cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:centralQueue options:nil];
}
return self;
}
// this would hit.... if I instantiated this in a storyboard of XIB file
- (void)awakeFromNib
{
if(!self.cbManager)
self.cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog(@"hey I found %@",[advertisementData description]);
}
- (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals
{
NSLog( @"I retrieved CONNECTED peripherals");
}
-(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals{
NSLog(@"This is it!");
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
NSString *messtoshow;
switch (central.state) {
case CBCentralManagerStateUnknown:
{
messtoshow=@"State unknown, update imminent.";
break;
}
case CBCentralManagerStateResetting:
{
messtoshow=@"The connection with the system service was momentarily lost, update imminent.";
break;
}
case CBCentralManagerStateUnsupported:
{
messtoshow=@"The platform doesn't support Bluetooth Low Energy";
break;
}
case CBCentralManagerStateUnauthorized:
{
messtoshow=@"The app is not authorized to use Bluetooth Low Energy";
break;
}
case CBCentralManagerStatePoweredOff:
{
messtoshow=@"Bluetooth is currently powered off.";
break;
}
case CBCentralManagerStatePoweredOn:
{
messtoshow=@"Bluetooth is currently powered on and available to use.";
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[_cbManager scanForPeripheralsWithServices:nil options:options];
break;
}
}
NSLog(@"%@", messtoshow);
}
@end
2条答案
按热度按时间nwsw7zdq1#
首先,您需要配置应用程序的音频会话,以允许支持音频的蓝牙连接。例如,您可以在应用程序委托-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中执行此操作。确保链接AVFoundation Framework并导入将使用它的头文件。
每个应用程序都有一个可以配置的音频会话单例。会话类别和模式(在这个例子中,我没有设置模式,所以它恢复到默认模式)声明了您的应用程序的意图,即您希望如何处理音频路由。它遵循一个重要的规则最后获胜。这意味着,如果用户插入头戴式耳机,或者在这种情况下插入作为免提外围设备(HFP)的蓝牙设备,则系统将自动将音频路由到头戴式耳机或蓝牙设备。用户的物理动作用于确定音频路由。但是,如果您希望为用户提供可用路由列表,Apple建议使用MPVolumeView类。
添加MPVolumeView的示例可以放在UIViewController子类viewDidLoad方法中。
从iOS7开始,你可以像这样获得所有输入
您可能感兴趣的portType是“BluetoothHFP”。portName属性通常是制造商/型号,这是您要向用户显示的内容。(我已经用一个非LE蓝牙的摩托罗拉恐龙检查过了,它很好用)
由于last in wins规则,您需要遵守这两个通知(包括iOS 7)。一个用于处理中断(例如电话或警报),第二个用于通知路线更改。路由更改通知与此问题相关。
对于iOS 6.x,您可以在myRouteChange中读取AVAudioSession的currentRoute属性:选择器来获取新的路由,因为当连接耳机或蓝牙设备时,将调用该选择器。
任何低于6.0的iOS版本都需要'now deprecated' AudioSessionServices类。这个类是一个C API,它允许你添加属性监听器,而不是通知。
我将在这张纸条上结束-你不总是从系统中得到你想要的。需要观察中断处理通知和大量的错误检查。我认为这是一个非常好的问题,我希望这能让你明白你想要实现什么。
njthzxwz2#
Swift版本