なかじまの開発ブログ

アプリ開発における備忘録などなど。

MENU

iPhoneの音量ボタンの押下イベントを検出【Objective-C】

こちらに素晴らしいサイトがありました。

frnk.hatenablog.jp

しかし、deprecatedが多いためiOS7.0以降でも動くようにした記事を残します。

こちらも参考にしました。
【iOS】【MPVolumeView】スライダー移動で音量を変更したときにシステムの音量表示のオーバーレイが表示されてしまうときの対処法 | わびさび少年のブログ



『.h』

#import <MediaPlayer/MediaPlayer.h>
#impoer <AudioToolbox/AudioToolbox.h>

@interface ○○○○ {
  float initialVolume;
  AVAudioSession *session;
}

@property (nonatomic) UISlider *volumeSlider; // システム側のスライダー

- (void)setVolumeNotification; // ボリュームボタン検出


『.m』

- (void)viewDidLoad {
  [super viewDidLoad];

  // ボリュームボタン検出
  [self setVolumeNotification];
    
    //MPVolumeViewを画面外から出す
    CGRect frame = CGRectMake(-100, -100, 100, 100);
    MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:frame];
    [volumeView sizeToFit];
    [self.view addSubview:volumeView];
    
    session = [AVAudioSession sharedInstance];
  [session setCategory:AVAudioSessionCategoryAmbient error:nil];
  [session setActive:YES error:nil];

  self.volumeSlider = nil;
  for (UIView *view in [volumeView subviews]) {
    if ([view.class.description isEqualToString:@"MPVolumeSlider"]) {
      self.volumeSlider = (UISlider *)view;
      break;
    }
  }

  initialVolume = self.volumeSlider.value;

    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
    [center addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}

- (void)setVolumeNotification {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
}

- (void)volumeChanged:(NSNotification *)notification{
    //明示的にボリューム変更がされた時のみ
    if ([[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeChangeReasonNotificationParameter"] isEqualToString:@"ExplicitVolumeChange"]) {

    //ここに押下処理を記述

    //一旦NSNotificationCenterからAVSystemController_SystemVolumeDidChangeNotificationを外して、ボリュームを元に戻す
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; 
    self.volumeSlider.value = initialVolume;
    [self performSelector:@selector(setVolumeNotification) withObject:nil afterDelay:0.2];
    }
}

- (void)applicationDidEnterBackground:(NSNotification *)notification {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
    [session setActive:NO error:nil];
}

- (void)applicationWillEnterForeground:(NSNotification *)notification {
    initialVolume = self.volumeSlider.value;
    [self setVolumeNotification];
    [session setActive:YES error:nil];
}