2009-12-02 209 views
16

我目前正在從事一個項目,該項目涉及從應用程序內的iphone音樂庫播放音樂。我正在使用MPMediaPickerController來允許用戶選擇他們的音樂並使用iPhone中的iPod音樂播放器進行播放。如何以編程方式檢測iPhone中的聽筒?

但是,當用戶插入耳機並將其取出時,我遇到了問題。音樂會無緣無故地停止播放。經過一些測試後,我發現當用戶從設備上拔下耳機時,iPod播放器將暫停播放。那麼是否有任何方法可以通過程序檢測耳機是否已拔下,以便我可以繼續播放音樂?或者有什麼辦法可以防止iPod播放器在用戶拔下耳機時暫停播放?

回答

9

爲AudioRoute改變通知你應該登記和實施要如何處理狂勝改變

// Registers the audio route change listener callback function 
    AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, 
            audioRouteChangeListenerCallback, 
            self); 

並且在回調之內,可以得到路由變更的原因

CFDictionaryRef routeChangeDictionary = inPropertyValue; 

    CFNumberRef routeChangeReasonRef = 
    CFDictionaryGetValue (routeChangeDictionary, 
      CFSTR (kAudioSession_AudioRouteChangeKey_Reason)); 

    SInt32 routeChangeReason; 

     CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); 

    if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) 
    { 
     // Headset is unplugged.. 

    } 
    if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable) 
    { 
     // Headset is plugged in..     
    } 
+0

ERM 1)wat的inPropertyValue?它不會在方法參數 中刪除2)CFDictionaryGetValue返回一個無法與CFNumberRef匹配的void指針。在返回值之前,我需要做任何投射嗎? – 2009-12-04 03:26:22

+0

嗯我設法編譯我的代碼,一切運行良好,但是當我插入或拔掉我的耳機沒有任何反應。 audioRouteChangeListenerCallback函數未被調用。在上面的函數旁邊還有其他的東西嗎? – 2009-12-04 08:30:12

+0

你應該在你的調用初始化AudioSession之後註冊監聽器函數..你是這麼做的嗎? – prakash 2009-12-04 09:17:50

2

我看到您正在使用MPMediaPlayer框架,但麥克風處理是使用AVAudioPlayer框架完成的,您需要將該框架添加到您的項目中。

蘋果網站的代碼來自AVAudioPlayer框架,我用它來處理用戶插入或移除蘋果麥克風耳機的干擾。

看看蘋果的iPhone Dev Center Audio Session Programming Guide

- (void) beginInterruption { 
    if (playing) { 
     playing = NO; 
     interruptedWhilePlaying = YES; 
     [self updateUserInterface]; 
    } 
} 

NSError *activationError = nil; 
- (void) endInterruption { 
    if (interruptedWhilePlaying) { 
     [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; 
     [player play]; 
     playing = YES; 
     interruptedWhilePlaying = NO; 
     [self updateUserInterface]; 
    } 
} 

我的代碼是有點不同的,一些本可以幫助你:

void interruptionListenerCallback (
            void *inUserData, 
            UInt32 interruptionState 
) { 
    // This callback, being outside the implementation block, needs a reference 
    // to the AudioViewController object 
    RecordingListViewController *controller = (RecordingListViewController *) inUserData; 

    if (interruptionState == kAudioSessionBeginInterruption) { 

     //NSLog (@"Interrupted. Stopping playback or recording."); 

     if (controller.audioRecorder) { 
      // if currently recording, stop 
      [controller recordOrStop: (id) controller]; 
     } else if (controller.audioPlayer) { 
      // if currently playing, pause 
      [controller pausePlayback]; 
      controller.interruptedOnPlayback = YES; 
     } 

    } else if ((interruptionState == kAudioSessionEndInterruption) && controller.interruptedOnPlayback) { 
     // if the interruption was removed, and the app had been playing, resume playback 
     [controller resumePlayback]; 
     controller.interruptedOnPlayback = NO; 
    } 
} 

void recordingListViewMicrophoneListener (
         void      *inUserData, 
         AudioSessionPropertyID inPropertyID, 
         UInt32     inPropertyValueSize, 
         const void    *isMicConnected 
         ) { 

    // ensure that this callback was invoked for a change to microphone connection 
    if (inPropertyID != kAudioSessionProperty_AudioInputAvailable) { 
     return; 
    } 

    RecordingListViewController *controller = (RecordingListViewController *) inUserData; 

    // kAudioSessionProperty_AudioInputAvailable is a UInt32 (see Apple Audio Session Services Reference documentation) 
    // to read isMicConnected, convert the const void pointer to a UInt32 pointer 
    // then dereference the memory address contained in that pointer 
    UInt32 connected = * (UInt32 *) isMicConnected; 

    if (connected){ 
     [controller setMicrophoneConnected : YES]; 
    } 
    else{ 
     [controller setMicrophoneConnected: NO];  
    } 

    // check to see if microphone disconnected while recording 
    // cancel the recording if it was 
    if(controller.isRecording && !connected){ 
     [controller cancelDueToMicrophoneError]; 
    } 
} 
4

如果你只是要檢查耳機是否在任何給定的時間插上,不聽路由變化,你可以簡單地做到以下幾點:

OSStatus error = AudioSessionInitialize(NULL, NULL, NULL, NULL); 
if (error) 
    NSLog("Error %d while initializing session", error); 

UInt32 routeSize = sizeof (CFStringRef); 
CFStringRef route; 

error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute, 
           &routeSize, 
           &route); 

if (error) 
    NSLog("Error %d while retrieving audio property", error); 
else if (route == NULL) { 
    NSLog(@"Silent switch is currently on"); 
} else if([route isEqual:@"Headset"]) { 
    NSLog(@"Using headphones"); 
} else { 
    NSLog(@"Using %@", route); 
} 

乾杯, 拉斐爾Colasante

+1

可以在這裏找到更好的這個實現:http://stackoverflow.com/questions/3728781/detect-if-headphones-not-microphone-are-plugged-在對一個-IOS裝置 – 2011-06-17 05:58:55

2

嘿傢伙只是檢查AddMusic示例應用程序。將解決所有的iPod相關的問題

首先註冊iPod播放器的通知與下列代碼

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 

    [notificationCenter 
    addObserver: self 
    selector: @selector (handle_PlaybackStateChanged:) 
    name:  MPMusicPlayerControllerPlaybackStateDidChangeNotification 
    object:  musicPlayer]; 

    [musicPlayer beginGeneratingPlaybackNotifications]; 

並實現以下代碼通知編譯時,我遇到2錯誤

- (void) handle_PlaybackStateChanged: (id) notification 
{ 

    MPMusicPlaybackState playbackState = [musicPlayer playbackState]; 

    if (playbackState == MPMusicPlaybackStatePaused) 
    { 
      [self playiPodMusic]; 
    } 
    else if (playbackState == MPMusicPlaybackStatePlaying) 
    { 

    } 
    else if (playbackState == MPMusicPlaybackStateStopped) 
    { 
     [musicPlayer stop]; 
    } 
} 
相關問題