2009-12-02 13 views
16

Attualmente sto lavorando a un progetto che prevede la riproduzione di musica dalla libreria musicale iphone all'interno dell'app all'interno. Sto usando MPMediaPickerController per consentire all'utente di selezionare la propria musica e riprodurla utilizzando il lettore musicale iPod all'interno dell'iPhone.Come rilevare automaticamente l'auricolare nell'iPhone?

Tuttavia, ho riscontrato un problema quando l'utente inserisce l'auricolare e lo rimuove. La musica smetterà improvvisamente di suonare senza motivo. Dopo alcuni test, ho scoperto che il lettore iPod metterà in pausa la riproduzione quando l'utente scollega l'auricolare dal dispositivo. Quindi c'è un modo per rilevare in modo programmato se l'auricolare è stato scollegato in modo da poter riprendere a suonare la musica? O esiste un modo per impedire che il lettore iPod si interrompa quando l'utente scollega l'auricolare?

risposta

9

è necessario registrarsi per AudioRoute cambiato la notifica e realizzare come si desidera gestire la rotta cambia

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

e all'interno del callback, è possibile ottenere il motivo per il cambio di itinerario

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

ehm sto avendo 2 errore durante la compilazione 1) wat's inPropertyValue? Non è stato riconosciuto nel parametro metodo 2) CFDictionaryGetValue restituisce un puntatore vuoto che è incomparabile con CFNumberRef. Devo fare un casting prima di restituire il valore? –

+0

hmm sono riuscito a compilare i miei codici e tutto funziona bene ma quando collego o scollego la cuffia non succede nulla. La funzione audioRouteChangeListenerCallback non è stata chiamata. C'è qualcos'altro che mi manca accanto alle funzioni sopra? –

+0

È necessario registrarsi per la funzione listener DOPO la chiamata all'inizializzazione di AudioSession. Lo fai in questo modo? – prakash

2

Vedo che si sta utilizzando MPMediaPlayer Framework, tuttavia la gestione del microfono viene eseguita utilizzando il framework AVAudioPlayer, che sarà necessario aggiungere al progetto.

Il sito Web di Apple include il codice del framework AVAudioPlayer che utilizzo per gestire le interruzioni da un utente che collega o rimuove le cuffie del microfono Apple.

Controllare Apple 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]; 
    } 
} 

Il mio codice è un po 'diverso e un po' di questo può aiutare:

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

Se si desidera solo per controllare se le cuffie sono inserite in un dato momento, senza ascoltare cambiamenti di rotta, si può semplicemente fare le seguenti:

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); 
} 

Cheers, Raffaello Colasante

+1

Un'implementazione molto migliore di questa può essere trovata qui: http://stackoverflow.com/questions/3728781/detect-if-headphones-not-microphone-are-plugged- in-a-un-ios dispositivo –

2

Hey i ragazzi controllano l'app di esempio AddMusic. Risolverà tutti i vostri problemi legati iPod

primo registro lettore iPod per la notifica con il seguente codice

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 

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

    [musicPlayer beginGeneratingPlaybackNotifications]; 

e implementare il seguente codice nella notifica

- (void) handle_PlaybackStateChanged: (id) notification 
{ 

    MPMusicPlaybackState playbackState = [musicPlayer playbackState]; 

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

    } 
    else if (playbackState == MPMusicPlaybackStateStopped) 
    { 
     [musicPlayer stop]; 
    } 
} 
Problemi correlati