52 votes

Comment détecter par programmation le commutateur de sourdine de l'iPhone ?

Je n'arrive pas à trouver dans le SDK comment détecter par programme le bouton/interrupteur de sourdine sur l'iPhone. Lorsque mon application joue de la musique de fond, elle répond correctement au bouton de volume sans que je n'aie de code à suivre, mais, lorsque j'utilise le bouton de sourdine, elle continue à jouer.

Comment puis-je tester la position de la sourdine ?

(REMARQUE : mon programme possède son propre interrupteur de sourdine, mais j'aimerais que l'interrupteur physique prenne le dessus).

Merci !

30voto

Olie Points 10528

Merci, JPM. En effet, le lien que vous fournissez mène à la bonne réponse (éventuellement. ;) Pour être complet (parce que S.O. devrait ê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.");
}

11voto

Chris Ladd Points 1473

J'ai répondu à une question similaire ici (lien) . 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;

    }

7voto

Jane Sales Points 10895

Certains codes dans d'autres réponses (y compris la réponse acceptée) peuvent ne pas fonctionner si vous n'êtes pas en mode ambiant, où l'interrupteur de sourdine est respecté.

J'ai écrit la routine ci-dessous pour passer en mode ambiant, lire l'interrupteur, 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;
}

5voto

Martin Cowie Points 1152

Pour connaître l'état du commutateur de sourdine y le contrôle du volume, j'ai écrit ces deux fonctions. Elles sont idéales si vous souhaitez avertir l'utilisateur avant qu'il n'essaie 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;
}

0voto

jpm Points 5933

Olie,

Je pense 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 des développeurs sur Apple.com :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X