Как программно определить выключатель звука iPhone? - PullRequest
44 голосов
/ 13 ноября 2008

Я не могу найти в SDK, как программно ощутить кнопку / выключение звука на iPhone. Когда мое приложение воспроизводит фоновую музыку, оно должным образом реагирует на кнопку громкости, и у меня нет кода, чтобы следовать этому, но когда я использую переключатель отключения звука, оно просто продолжает воспроизводиться.

Как проверить положение отключения звука?

(ПРИМЕЧАНИЕ. У моей программы есть собственный переключатель отключения звука, но я бы хотел, чтобы физический переключатель переопределил это.)

Ответы [ 10 ]

29 голосов
/ 15 ноября 2008

Спасибо, JPM. Действительно, ссылка, которую вы предоставляете, приводит к правильному ответу (в конце концов.;) Для полноты (поскольку S.O. должен быть источником БЫСТРЫХ ответов!) ...

// "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.");
}
11 голосов
/ 16 января 2011

Я ответил на аналогичный вопрос здесь (ссылка) . Соответствующий код:

 -(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;

    }
7 голосов
/ 02 августа 2011

Часть кода в других ответах (включая принятый ответ) может не работать, если вы не находитесь в окружающем режиме, где соблюден переключатель отключения звука.

Я написал подпрограмму ниже, чтобы переключиться на ambient, прочитать переключатель, а затем вернуться к настройкам, которые мне нужны в моем приложении.

-(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;
}
5 голосов
/ 05 августа 2010
-(BOOL)isDeviceMuted
{
 CFStringRef state;
 UInt32 propertySize = sizeof(CFStringRef);
 AudioSessionInitialize(NULL, NULL, NULL, NULL);
 AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
 return (CFStringGetLength(state) > 0 ? NO : YES);
}
5 голосов
/ 03 августа 2010

Чтобы узнать состояние выключателя звука и регулятора громкости, я написал эти две функции. Они идеально подходят, если вы хотите предупредить пользователя, прежде чем он попытается создать аудиовыход.

-(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;
}
4 голосов
/ 22 апреля 2010

Я следовал общей теории здесь и заставил это работать http://inforceapps.wordpress.com/2009/07/08/detect-mute-switch-state-on-iphone/

Вот резюме: Воспроизведите короткий тихий звук. Время, сколько требуется, чтобы играть. Если выключить звук, воспроизведение звука вернется намного короче, чем сам звук. Я использовал звук 500 мс, и если звук воспроизводился меньше, чем на этот раз, то выключатель звука был включен. Я использую Audio Services для воспроизведения тихого звука (который всегда учитывает выключение звука). В этой статье говорится, что вы можете использовать AVAudioPlayer для воспроизведения этого звука. Если вы используете AVAudioPlayer, я предполагаю, что вам нужно настроить категорию вашей AVAudioSession, чтобы соблюдать выключение звука, но я не пробовал `.

4 голосов
/ 13 ноября 2008

Olie,

Полагаю, вы можете найти ответ на свой вопрос здесь:

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

Я предполагаю, что у вас есть доступ к форумам разработчиков на Apple.com:)

3 голосов
/ 09 декабря 2014

Использование Ambient для воспроизведения видео и PlayAndRecord для записи видео на экране камеры решает проблему в нашем случае.

Код в приложении: didFinishLaunchingWithOptions:

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

Код в viewWillAppear на cameraController, если вам нужно использовать камеру или запись в вашем приложении

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

Отображаемый код исчезнет с камеры на контроллере

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

Используя эти строки, наше приложение записывает и воспроизводит видео и переключатель отключения звука отлично работает как на iOS8, так и на iOS7 !!!

2 голосов
/ 29 марта 2018

Для Swift

Ниже рамки отлично работает в устройстве

https://github.com/akramhussein/Mute

Просто установите с помощью pod или загрузите с Git

pod 'Mute'

и используйте код, указанный ниже

import UIKit
import Mute

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel! {
        didSet {
            self.label.text = ""
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Notify every 2 seconds
        Mute.shared.checkInterval = 2.0

        // Always notify on interval
        Mute.shared.alwaysNotify = true

        // Update label when notification received
        Mute.shared.notify = { m in
            self.label.text = m ? "Muted" : "Not Muted"
        }

        // Stop after 5 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            Mute.shared.isPaused = true
        }

        // Re-start after 10 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
            Mute.shared.isPaused = false
        }
    }

}
1 голос
/ 25 декабря 2008

Вот два примера, как использовать AudioSessionInitialize: http://www.restoroot.com/Blog/2008/12/25/audiosessioninitialize-workarounds/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...