2008-11-13 6 views
39

Je n'arrive pas à trouver dans le SDK comment programmer le bouton/commutateur de sourdine de l'iPhone. Quand mon application joue de la musique de fond, elle répond correctement au bouton de volume sans que j'aie de code à suivre, mais quand j'utilise le bouton de sourdine, ça continue à jouer.Comment détecter par programmation l'interrupteur de mise en sourdine de l'iPhone?

Comment tester la position de la sourdine?

(NOTE: Mon programme a son propre commutateur muet, mais je voudrais l'interrupteur physique pour remplacer cela.)

Merci!

Répondre

29

Merci, JPM. En effet, le lien vous conduit à fournir la bonne réponse; Pour être complet (car ils doivent donc être une source de réponses rapides!) ...

// "Ambient" makes it respect the mute switch 
// Must call this once to init session 
if (!gAudioSessionInited) 
{ 
    AudioSessionInterruptionListener inInterruptionListener = NULL; 
    OSStatus error; 
    if ((error = AudioSessionInitialize (NULL, NULL, inInterruptionListener, NULL))) 
    { 
     NSLog(@"*** Error *** error in AudioSessionInitialize: %d.", error); 
    } 
    else 
    { 
     gAudioSessionInited = YES; 
    } 
} 

SInt32 ambient = kAudioSessionCategory_AmbientSound; 
if (AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (ambient), &ambient)) 
{ 
    NSLog(@"*** Error *** could not set Session property to ambient."); 
} 
+0

si je connecte la valeur de l'ambiance après, je serai toujours retourné 1634558569 peu importe si je suis coupé ou non. Une idée? –

+0

Ne semble pas fonctionner sur iOS 8. –

+0

"Ne fonctionne pas" comment? Qu'est-ce que tu as fait? Qu'espériez-vous arriver? Qu'est-il arrivé, à la place? Si vous fournissez plus d'informations, je vais essayer de mettre à jour ma réponse. Merci! – Olie

5

Olie,

je crois que vous pouvez trouver la réponse à votre question ici:

https://devforums.apple.com/message/1135#1135

Je suppose que vous avez accès aux forums de développeurs sur Apple.com :)

+0

Sho '' nuff! Récapitulatif rapide: "AudioSessionSetProperty pour régler l'AudioCategory sur Ambient" (Je crois que c'est correct de parler de logiciel d'expédition ...) Merci! – Olie

4

J'ai suivi la théorie générale ici et nous avons obtenu cela fonctionne http://inforceapps.wordpress.com/2009/07/08/detect-mute-switch-state-on-iphone/

Voici un résumé: Faites une courte son silence. Temps combien de temps cela prend pour jouer. Si l'interrupteur de sourdine est activé, la lecture du son reviendra beaucoup plus courte que le son lui-même. J'ai utilisé un son de 500 ms et si le son était joué en moins de cette durée, l'interrupteur de mise en sourdine était activé. J'utilise les services audio pour jouer le son silencieux (qui honore toujours le commutateur muet). Cet article indique que vous pouvez utiliser AVAudioPlayer pour lire ce son. Si vous utilisez AVAudioPlayer, je suppose que vous aurez besoin de configurer la catégorie de votre AVAudioSession pour honorer le switch muet, mais je ne l'ai pas essayé ».

5

Pour connaître l'état du commutateur Mute et le contrôle du volume j'ai écrit ces deux fonctions. Ceux-ci sont idéaux si vous souhaitez avertir l'utilisateur avant d'essayer de créer une sortie audio.

-(NSString*)audioRoute 
{ 
    CFStringRef state; 
    UInt32 propertySize = sizeof(CFStringRef); 
    OSStatus n = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state); 
    if(n) 
    { 
     // TODO: Throw an exception 
     NSLog(@"AudioSessionGetProperty: %@", osString(n)); 
    } 

    NSString *result = (NSString*)state; 
    [result autorelease]; 
    return result; 
} 

-(Float32)audioVolume 
{ 
    Float32 state; 
    UInt32 propertySize = sizeof(CFStringRef); 
    OSStatus n = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputVolume, &propertySize, &state); 
    if(n) 
    { 
     // TODO: Throw an exception 
     NSLog(@"AudioSessionGetProperty: %@", osString(n)); 
    } 
    return state; 
} 
5
-(BOOL)isDeviceMuted 
{ 
CFStringRef state; 
UInt32 propertySize = sizeof(CFStringRef); 
AudioSessionInitialize(NULL, NULL, NULL, NULL); 
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state); 
return (CFStringGetLength(state) > 0 ? NO : YES); 
} 
+3

(CFStringGetLength (état) > 0? NON: OUI) est identique à (CFStringGetLength (état) <= 0) – Daniel

+0

@simpleBob comment détecter la valeur du bouton de sourdine de l'iphone. (e.x si la sourdine de l'iphone est sur la position (en sourdine) comment détecter la valeur de silence). –

+0

@ Yuvaraj.M Voilà en quoi consiste cette question. Sélectionnez votre réponse préférée;) Par exemple, vous pouvez simplement exécuter la méthode ci-dessus, qui renvoie YES si le périphérique est muet. – Daniel

10

je répondu à une question similaire here (link). Le code correspondant:

-(BOOL)silenced { 
    #if TARGET_IPHONE_SIMULATOR 
     // return NO in simulator. Code causes crashes for some reason. 
     return NO; 
    #endif 

    CFStringRef state; 
    UInt32 propertySize = sizeof(CFStringRef); 
    AudioSessionInitialize(NULL, NULL, NULL, NULL); 
    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state); 
    if(CFStringGetLength(state) > 0) 
      return NO; 
    else 
      return YES; 

    } 
+1

Cela fonctionne très bien. –

+0

Exactement ce que je cherchais. Merci Pirripli! –

+1

Cela ne fonctionne pas lorsque les écouteurs sont branchés. AudioSessionGetProperty pour la route audio renvoie «Headphone», quel que soit le commutateur de sourdine. – yood

7

Une partie du code dans d'autres réponses (y compris la réponse acceptée) ne peut fonctionner si vous n'êtes pas en mode ambiant, où est respecté le commutateur muet.

J'ai écrit la routine ci-dessous pour passer en mode ambiant, lire le commutateur, puis revenir aux paramètres dont j'ai besoin dans mon application.

-(BOOL)muteSwitchEnabled { 

#if TARGET_IPHONE_SIMULATOR 
    // set to NO in simulator. Code causes crashes for some reason. 
    return NO; 
#endif 

// go back to Ambient to detect the switch 
AVAudioSession* sharedSession = [AVAudioSession sharedInstance]; 
[sharedSession setCategory:AVAudioSessionCategoryAmbient error:nil]; 

CFStringRef state; 
UInt32 propertySize = sizeof(CFStringRef); 
AudioSessionInitialize(NULL, NULL, NULL, NULL); 
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state); 

BOOL muteSwitch = (CFStringGetLength(state) <= 0); 
NSLog(@"Mute switch: %d",muteSwitch); 

// code below here is just restoring my own audio state, YMMV 
_hasMicrophone = [sharedSession inputIsAvailable]; 
NSError* setCategoryError = nil; 

if (_hasMicrophone) { 

    [sharedSession setCategory: AVAudioSessionCategoryPlayAndRecord error: &setCategoryError]; 

    // By default PlayAndRecord plays out over the internal speaker. We want the external speakers, thanks. 
    UInt32 ASRoute = kAudioSessionOverrideAudioRoute_Speaker; 
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, 
          sizeof (ASRoute), 
          &ASRoute 
          ); 
} 
else 
    // Devices with no mike don't support PlayAndRecord - we don't get playback, so use just playback as we don't have a microphone anyway 
    [sharedSession setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError]; 

if (setCategoryError) 
    NSLog(@"Error setting audio category! %@", setCategoryError); 

return muteSwitch; 
} 
3

En utilisant le mode ambiante pour la lecture d'une vidéo et le mode PlayAndRecord pour l'enregistrement d'une vidéo sur l'écran de la caméra, résout le problème dans notre cas.

Le code en application: didFinishLaunchingWithOptions:

NSError *error = nil; 
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&error]; 
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeVideoRecording error:&error]; 
[[AVAudioSession sharedInstance] setActive:YES error:&error]; 

Le code viewWillAppear sur cameraController, si vous devez utiliser l'appareil photo ou l'enregistrement dans votre application

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 

Le code viewWillDisappear sur cameraController

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; 

En utilisant ces lignes notre application r ecords et joue un interrupteur vidéo et muet fonctionne parfaitement sous iOS8 et iOS7 !!!

+0

Pourriez-vous s'il vous plaît m'aider, j'ai la fonction d'appel voip dans mon application, je dois jouer de la musique/sonnerie lorsque l'utilisateur reçoit un appel. Je veux jouer cette sonnerie même si l'application est en mode d'arrière-plan. Si j'utilise "AVAudioSessionCategoryPlayAndRecord" il ne fonctionne pas avec le commutateur mute, si j'utilise "AVAudioSessionCategoryAmbient", il ne joue pas en arrière-plan. S'il vous plaît donnez-moi des suggestions pour réaliser les deux cas. –

Questions connexes