2016年04月26日

[iOS] リモコン付きイヤフォン(ヘッドフォン)のイベントを監視する

iOS担当のエモトです.先日,大洗に行ってきました.この場所はあのシーンで見た!と街を見て回ってきました.その旅行のあと,映画館にいったのですが,このシーンはあの場所で見た!と,不思議な円環の理に陥ってしまいました.

音声や音楽系アプリを取り扱う場合,イヤフォン制御が大切になります.

(a) イヤフォンを確認する
端末にイヤフォンがつながっているかは以下のようにすれば調べることができます.
#import < AVFoundation/AVFoundation.h >

- (BOOL)hasHeadphone{
    BOOL hasHeadphones = false;
    AVAudioSessionRouteDescription* route = [[AVAudioSession sharedInstance] currentRoute];
    for (AVAudioSessionPortDescription* desc in [route outputs]){
        NSString *portType = desc.portType;
        if ([portType isEqualToString:AVAudioSessionPortHeadphones]){
            || [portType isEqualToString:AVAudioSessionPortBluetoothA2DP]){
            hasHeadphones = true;
        }
    }
    return hasHeadphones;
}
しかしながら,その時だけの状態が取得できても機能不足です.イヤフォンが端末から差し抜きされたときのイベントは以下のようにすれば監視することができます.
// 監視を始める
- (void)startObservation{
    [[AVAudioSession sharedInstance] setActive:true error:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(audioSessionRouteChanged:)
                                                 name:AVAudioSessionRouteChangeNotification
                                               object:nil];
}

// 監視を終える
- (void)removeObservation{
    [[AVAudioSession sharedInstance] setActive:false error:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AVAudioSessionRouteChangeNotification
                                                  object:nil];
}

// ヘッドフォンが差し向きされた
- (void)audioSessionRouteChanged:(NSNotification*)notification
{
}

(b) リモコンを確認する
リモコン付きイヤフォンの再生や停止などのイベントは MPRemoteCommandCenter を使えば監視することができます.
#import < MediaPlayer/MediaPlayer.h >

// 監視を始める
-(void)addRemoteCommandCenter{
    MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
    [rcc.togglePlayPauseCommand addTarget:self action:@selector(toggle:)];
    [rcc.playCommand addTarget:self action:@selector(play:)];
    [rcc.pauseCommand addTarget:self action:@selector(pause:)];
    [rcc.nextTrackCommand addTarget:self action:@selector(nextTrack:)];
    [rcc.previousTrackCommand addTarget:self action:@selector(prevTrack:)];	
}

// 監視を終える
-(void)removeRemoteCommandCenter{
    MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
    [rcc.togglePlayPauseCommand removeTarget:self];
    [rcc.playCommand removeTarget:self];
    [rcc.pauseCommand removeTarget:self];
    [rcc.nextTrackCommand removeTarget:self];
    [rcc.previousTrackCommand removeTarget:self];
}

// 再生・停止のトグルボタンが押された(他のメソッドは省略)
- (void)toggle:(MPRemoteCommandEvent*)event{
    // 何かしらの処理
}
ただし,MPRemoteCommandCenterはiOS7.1から実装されました.iOS7.0も対象する場合はremoteControlReceivedWithEventを使います(ドキュメントではMPRemoteCommandCenterの使用を推奨しています).個人的に,後者はcanBecomeFirstResponderを上書きしないとならないので,実装箇所を限定してしまい,ちょっと使いにくいなと思ってます.
// 監視を始める
- (void)hogehoge{
    id obj = NSClassFromString(@"MPRemoteCommandCenter");
    if (obj) {
        // MPRemoteCommandCenterが使える
        [self addRemoteCommandCenter];
    }else{
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
        [self becomeFirstResponder];

        // 監視を終える時は
        // [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
        // [self resignFirstResponder];
    }
}

// trueに上書きする
- (BOOL)canBecomeFirstResponder{
    return true;
}

// イベントが起こった
- (void)remoteControlReceivedWithEvent:(UIEvent*)receivedEvent{
    if (receivedEvent.type == UIEventTypeRemoteControl) {
        UIEventSubtype subtype = receivedEvent.subtype;
        if (subtype == UIEventSubtypeRemoteControlPlay){
        }else if (subtype == UIEventSubtypeRemoteControlPause){
        }else if (subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
        }else if (subtype == UIEventSubtypeRemoteControlPreviousTrack){
        }else if (subtype == UIEventSubtypeRemoteControlNextTrack){
        }
    }
}
posted by Seesaa京都スタッフ at 12:52| Comment(0) | iOS | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: