Search code examples
iosheadphonesexternal-accessory

Can't get a notification when connecting an external accessory to the 3.5 mm headphones jack


I've been trying to get this to work for a while now. I've done everything they say in the documentation and still got nothing.

This is the code in my app delegate that registers for local notifications:

- (void) registerForLocalNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(_accessoryConnected:)
                                             name:EAAccessoryDidConnectNotification
                                           object:nil];


[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(_accessoryDisconnected:)
                                             name:EAAccessoryDidDisconnectNotification
                                           object:nil];

[[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications]; }

The above is called from applicationDidFinishLaunching.

Here is the code of the connect/disconnect methods:

- (void) _accessoryConnected:(NSNotification *)notification {
          NSLog(@"_accessoryConnected"); }

- (void) _accessoryDisconnected:(NSNotification*)notification {
NSLog(@"_accessoryDisconnected"); }


-(void) accessoryDidDisconnect:(EAAccessory *) accessory {
NSLog(@"accessoryDidDisconnect"); }

Tried connecting the headphones that come with the iPhone and got nothing, same for my external accessory I want to integrate with the app.

Please help, Thanks, Shaul.


Solution

  • You should use AudioSessionPropertyListener for this. EAAccessory notifications are for hardware that connects to the 30 pin port. Add this listener in viewDidLoad and remove it in ViewDidUnLoad

    AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioSessionPropertyListener, nil);
    

    Add the following methods in the view controller.

    BOOL isHeadsetPluggedIn() {
        UInt32 routeSize = sizeof (CFStringRef);
        CFStringRef route;
    
        OSStatus error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute,
                                                  &routeSize,
                                                  &route
                                                  );    
        NSLog(@"%@", route);
        return (!error && (route != NULL) && ([(NSString*)route rangeOfString:@"Head"].location != NSNotFound));
    }
    
    void audioSessionPropertyListener(void* inClientData, AudioSessionPropertyID inID,
                                      UInt32 inDataSize, const void* inData) {
        UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
    
        // Determines the reason for the route change, to ensure that it is not
        //      because of a category change.
        CFDictionaryRef routeChangeDictionary = inData;    
        CFNumberRef routeChangeReasonRef = CFDictionaryGetValue (routeChangeDictionary,CFSTR (kAudioSession_AudioRouteChangeKey_Reason));
    
        SInt32 routeChangeReason;    
        CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);
    
        // "Old device unavailable" indicates that a headset was unplugged, or that the
        //  device was removed from a dock connector that supports audio output. 
        if (routeChangeReason != kAudioSessionRouteChangeReason_OldDeviceUnavailable)
            return;
    
        if (!isHeadsetPluggedIn()) 
        {
            AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
        }
        else 
        {
            UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
            AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
        }    
    }
    

    Note, I got this code long ago from somewhere and it worked for me. Cannot attribute the source now as I don't know where I got it from.