我正在开发一款与蓝牙2.1进行通信的iOS应用。 应用程序在变为活动状态时连接到BT。如果应用程序转到后台并再次变为活动状态,它可以正常工作。
但我刚发现一个问题:
如果我关闭BT模块电源,应用程序会收到通知,我会执行以下操作:
- (void)accessoryDidDisconnect:(EAAccessory *)accessory
{
NSLog(@"EAController::accessoryDidDisconnect:");
_selectedAccessory = nil;
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"Lost connection. " delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:YES forKey:@"Lost Communication"];
[self closeSession];
}
然后我重新打开模块电源,转到设置 - >蓝牙,将BT模块连接到iPhone,活动应用程序(从后台返回),无法启动EASession:
if (_session == nil)
{
NSLog(@"EAController::openSession");
[_selectedAccessory setDelegate:self];
_session = [[EASession alloc] initWithAccessory:[self selectedAccessory] forProtocol:_protocolString];
if (_session)
{
// Set up delegate........
}
else
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey:Unit_Has_Connection_UserDefault_Key];
NSLog(@"creating session failed");
}
}
启动_accessoryList和_selectedAccessory:
_accessoryList = [[NSMutableArray alloc] initWithArray:[[EAAccessoryManager sharedAccessoryManager] connectedAccessories]];
_selectedAccessory = [_accessoryList objectAtIndex:0];
我发现_accessoryList有我正在使用的附件但它的“Protocols”是空的。
$12 = 0x1dd58050 <__NSArrayI 0x1dd58050>(
<EAAccessory: 0x1dd1dce0> {
connected:YES
connectionID:XXX
name: XXX
manufacturer: XXX
modelNumber: XXX
serialNumber:
firmwareRevision: XXX
hardwareRevision: XXX
macAddress: XXX
protocols: (
)
delegate: (null)
}
)
如果我杀了应用程序并重新启动,它可以正常工作。
有谁知道如何解决这个问题?
这个问题类似于this one,但在不同的情况下发生,这个问题的答案似乎并没有解决我的问题。
答案 0 :(得分:1)
经过几天寻找解决方案后,我终于解决了这个问题(或者我希望我能解决它)。我在这里发布我的答案,所以如果有人有同样的问题可以有想法。
你永远不能相信EAAccessoryManager,它可能有鬼配件。因此,使用以下命令启动_accessoryList并不总是有效。
_accessoryList = [[NSMutableArray alloc] initWithArray:[[EAAccessoryManager sharedAccessoryManager] connectedAccessories]];
如果您使用ghost配件启动accessoryList,请确保您无法成功启动EASession。
正确的方法是使用this answer中描述的EAAccessory通知,但它没有详细说明如何进行。
首先,您需要创建第二个通知:
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(accessoryConnected:) name:EAAccessoryDidConnectNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(accessoryDisconnected:) name:EAAccessoryDidConnectNotification object:nil];
[[EAAccessoryManager sharedAccessoryManager]registerForLocalNotifications];
然后在accessoryConnected和accessoryDisconnected中,您可以执行以下操作。
- (void)accessoryConnected:(NSNotification *)notification
{
NSLog(@"EAController::accessoryConnected");
EAAccessory *connectedAccessory = [[notification userInfo] objectForKey:EAAccessoryKey];
[[self accessoryList] addObject:connectedAccessory];
if ([_accessoryList count])
{
_selectedAccessory = [_accessoryList objectAtIndex:0];
NSArray *protocolStrings = [_selectedAccessory protocolStrings];
if ([protocolStrings count]) {
self.protocolString = [protocolStrings objectAtIndex:0];
[self openSession];
}
}
}
- (void)accessoryDisconnected:(NSNotification *)notification
{
EAAccessory *disconnectedAccessory = [[notification userInfo] objectForKey:EAAccessoryKey];
int disconnectedAccessoryIndex = 0;
for(EAAccessory *accessory in [self accessoryList]) {
if ([disconnectedAccessory connectionID] == [accessory connectionID]) {
break;
}
disconnectedAccessoryIndex++;
}
if (disconnectedAccessoryIndex < [[self accessoryList] count]) {
[[self accessoryList ] removeObjectAtIndex:disconnectedAccessoryIndex];
} else {
NSLog(@"could not find disconnected accessory in accessory list");
}
NSLog(@"_accessory did disconnect: %@",_accessoryList);
}
答案 1 :(得分:1)
从背景返回时我也有问题重新连接到我的配件,特别是在让我们说8h +闲置之后。仅依靠EAAccessoryDidConnectNotification / Disconnect(而不是可以提供ghost设备的EAAccessoryManager)的解决方案看起来大部分时间都能正常工作
但是,如果两个应用程序正在使用我们的配件,一旦手机/打击垫被唤醒,它可能会出现故障。第一个进入前台的应用程序最终会收到连接通知。但是当在第二个应用程序中交换时 - 它只会收到断开连接通知,而不是连接。在这里,我很难确定我们是否有连接配件,因为我不能信任EAAccessoryManager。
答案 2 :(得分:1)
我发现当EAAccessory重新连接时,您会看到附件对象的两次刷新。第一个没有协议字符串,几秒钟后,相同的附件(具有相同的连接ID)再次出现在协议字符串中。结构化我的代码s.t.根据Apple的推荐技术,它会忽略任何没有协议字符串的附件。
答案 3 :(得分:-1)
我相信您的配件必须与MFI(Made for iPhone,ipAd和iPod touch)芯片一起定义协议,以支持iDevice和i之间的通信。附件。您需要检查固件团队以及Apple MFI计划。该协议需要添加到&#34;支持的外部附件协议&#34;提交申请文件。