2013-10-24 147 views
1

爲了讓我的iPhone應用程序中的耳機可能插入或拔出耳機,並正確反應;我用下面樣的代碼,在我的幾個類:AudioSessionAddPropertyListener無緣無故召喚的回撥功能

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    ….. 
    routeChangeID=kAudioSessionProperty_AudioRouteChange; 
    AudioSessionAddPropertyListener(routeChangeID,rvcHandleRouteChange,(__bridge void *)(self)); 
} 

……. 

void rvcHandleRouteChange(void *inUserData,AudioSessionPropertyID inPropertyID, 
          UInt32 inPropertyValueSize,const void *inPropertyValue) 
{ 
    NSLog(@"Hi rvcHandleRouteChange has been called."); 
    if (inPropertyID!=kAudioSessionProperty_AudioRouteChange) NSLog(@"WRONG CALL!!!"); 
    // Do some useful work …. 
} 

,似乎工作相當好,除了在一個情況下rvcHandleRouteChange回調函數被調用時沒有明顯的原因。即使通過測試來過濾錯誤的呼叫,它們也不會顯示爲「錯誤呼叫」。 我的意思是,沒有我的電話就可以插入或拔下任何耳機。 因此,這給我很大的麻煩。

任何人都知道爲什麼會發生這種情況?

回答

1

1:路由更改呼叫甚至可能發生兩次。例如,如果您插入耳機(路由更改原因碼相同)。

2:一旦將音頻會話設置爲活動狀態,就會調用RouteChange。這意味着至少一次。

也許你正在實施自己的音頻中斷,在哪裏激活/停用音頻會話?

這裏爲任何使用(我用playAndRecord類)礦路線變化監聽[更新爲iOS7]:

#pragma mark Route change listener 
// ********************************************************************************************************* 
// *********** Route change listener *********************************************************************** 
// ********************************************************************************************************* 
-(void)routeChanged:(NSNotification*)notification { 

    NSLog(@"]-----------------[ Audio Route Change ]--------------------["); 

    AVAudioSession *session = [AVAudioSession sharedInstance]; 

    //AVAudioSessionRouteDescription* prevRoute = [[notification userInfo] objectForKey:AVAudioSessionRouteChangePreviousRouteKey]; 

    // Reason 
    NSInteger reason = [[[notification userInfo] objectForKey:AVAudioSessionRouteChangeReasonKey] integerValue]; 
    switch (reason) { 
     case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory: 
      NSLog(@"] Audio Route: The route changed because no suitable route is now available for the specified category."); 
      break; 
     case AVAudioSessionRouteChangeReasonWakeFromSleep: 
      NSLog(@"] Audio Route: The route changed when the device woke up from sleep."); 
      break; 
     case AVAudioSessionRouteChangeReasonOverride: 
      NSLog(@"] Audio Route: The output route was overridden by the app."); 
      break; 
     case AVAudioSessionRouteChangeReasonCategoryChange: 
      NSLog(@"] Audio Route: The category of the session object changed."); 
      break; 
     case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: 
      NSLog(@"] Audio Route: The previous audio output path is no longer available."); 
      break; 
     case AVAudioSessionRouteChangeReasonNewDeviceAvailable: 
      NSLog(@"] Audio Route: A preferred new audio output path is now available."); 
      break; 
     case AVAudioSessionRouteChangeReasonUnknown: 
      NSLog(@"] Audio Route: The reason for the change is unknown."); 
      break; 
     default: 
      NSLog(@"] Audio Route: The reason for the change is very unknown."); 
      break; 
    } 

    // Output 
    AVAudioSessionPortDescription *output = [[session.currentRoute.outputs count]?session.currentRoute.outputs:nil objectAtIndex:0]; 
    if ([output.portType isEqualToString:AVAudioSessionPortLineOut]) { 
     NSLog(@"] Audio Route: Output Port: LineOut"); 
    } 
    else if ([output.portType isEqualToString:AVAudioSessionPortHeadphones]) { 
     NSLog(@"] Audio Route: Output Port: Headphones"); 
    } 
    else if ([output.portType isEqualToString:AVAudioSessionPortBluetoothA2DP]) { 
     NSLog(@"] Audio Route: Output Port: BluetoothA2DP"); 
    } 
    else if ([output.portType isEqualToString:AVAudioSessionPortBuiltInReceiver]) { 
     NSLog(@"] Audio Route: Output Port: BuiltInReceiver"); 
    } 
    else if ([output.portType isEqualToString:AVAudioSessionPortBuiltInSpeaker]) { 
     NSLog(@"] Audio Route: Output Port: BuiltInSpeaker"); 
    } 
    else if ([output.portType isEqualToString:AVAudioSessionPortHDMI]) { 
     NSLog(@"] Audio Route: Output Port: HDMI"); 
    } 
    else if ([output.portType isEqualToString:AVAudioSessionPortAirPlay]) { 
     NSLog(@"] Audio Route: Output Port: AirPlay"); 
    } 
    else if ([output.portType isEqualToString:AVAudioSessionPortBluetoothLE]) { 
     NSLog(@"] Audio Route: Output Port: BluetoothLE"); 
    } 
    else { 
     NSLog(@"] Audio Route: Output Port: Unknown: %@",output.portType); 
    } 

    // Input 
    AVAudioSessionPortDescription *input = [[session.currentRoute.inputs count] ? session.currentRoute.inputs:nil objectAtIndex:0]; 

    if ([input.portType isEqualToString:AVAudioSessionPortLineIn]) { 
     NSLog(@"] Audio Route: Input Port: LineIn"); 
    } 
    else if ([input.portType isEqualToString:AVAudioSessionPortBuiltInMic]) { 
     NSLog(@"] Audio Route: Input Port: BuiltInMic"); 
    } 
    else if ([input.portType isEqualToString:AVAudioSessionPortHeadsetMic]) { 
     NSLog(@"] Audio Route: Input Port: HeadsetMic"); 
    } 
    else if ([input.portType isEqualToString:AVAudioSessionPortBluetoothHFP]) { 
     NSLog(@"] Audio Route: Input Port: BluetoothHFP"); 
    } 
    else if ([input.portType isEqualToString:AVAudioSessionPortUSBAudio]) { 
     NSLog(@"] Audio Route: Input Port: USBAudio"); 
    } 
    else if ([input.portType isEqualToString:AVAudioSessionPortCarAudio]) { 
     NSLog(@"] Audio Route: Input Port: CarAudio"); 
    } 
    else { 
     NSLog(@"] Audio Input Port: Unknown: %@",input.portType); 
    } 

    NSLog(@"]--------------------------[ ]-----------------------------["); 

} 

記住要添加的觀察者由於音頻會議的代表已被棄用過:

[[NSNotificationCenter defaultCenter] addObserver: self 
               selector: @selector(audioInterruption:) 
                name: AVAudioSessionInterruptionNotification 
                object: nil]; 
如果(CFArrayGetCount(outputs)> 0)改變爲:if(outputs && CFArrayGetCount(outputs)> 0),則需要更改iOS 8模擬器中的
+0

。 –