오디오 제어

Android 2014. 1. 28. 08:45
재생/볼륨 컨트롤
  • 어떤 Audio Stream을 사용할지 선택한다. 일반적인 음악 재생은 STREAM_MUSIC을 선택한다. [다른 옵션 보기]
  • 하드웨어 볼륨키는 현재 재생중인 것을 컨트롤한다. (재생중인 것이 없을 때는 전화벨 볼륨 조절)
    특정 Audio Stream의 볼륨을 조절하고 싶다면 아래와 같이 한다.
  • setVolumeControlStream(AudioManager.STREAM_MUSIC);
  • 하드웨어 컨트롤키(블루투스 헤드셋등에 있는)를 제어하기 위해서는 아래와 같이 한다.
    <receiver android:name=".RemoteControlReceiver">
       
    <intent-filter>
           
    <action android:name="android.intent.action.MEDIA_BUTTON" />
       
    </intent-filter>
    </receiver>
    public class RemoteControlReceiver extends BroadcastReceiver {
       
    @Override
       
    public void onReceive(Context context, Intent intent) {
           
    if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
               
    KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
               
    if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) {
                   
    // Handle key press.
               
    }
           
    }
       
    }
    }

    만약, 코드상에서 Receiver를 등록/해제하려면 아래와 같이 한다.

    AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
    ...

    // Start listening for button presses
    am
    .registerMediaButtonEventReceiver(RemoteControlReceiver);
    ...

    // Stop listening for button presses
    am
    .unregisterMediaButtonEventReceiver(RemoteControlReceiver);

    그런데, BroadcastReceiver는 일반적으로 Activity/Fragment등이 Invisible될 때 해제되므로 문제가 있다 (아래 내용에서 해결)

Audio Focus
  • 여러개의 앱들이 모두 음악을 재생하고자 하면 문제가 있기 때문에, 안드로이드 시스템에서 제어를 해야한다.
  • Focus를 가지고 오기 위해서는 아래와 같이 한다.

    AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
    ...

    // Request audio focus for playback
    int result = am.requestAudioFocus(afChangeListener,
                                     
    // Use the music stream.
                                     
    AudioManager.STREAM_MUSIC,
                                     
    // Request permanent focus.
                                     
    AudioManager.AUDIOFOCUS_GAIN);
       
    if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        am
    .registerMediaButtonEventReceiver(RemoteControlReceiver);
       
    // Start playback.
    }
  • Focus를 반납하려면 아래와 같이 한다.

    // Abandon audio focus when playback complete    
    am
    .abandonAudioFocus(afChangeListener)
  • "Ducking" - Focus를 잃어도(다른 앱이 요청시) 계속 재생을 하고 싶다면 , Focus를 가져올때 아래와 같이 한다.

    // Request audio focus for playback
    int result = am.requestAudioFocus(afChangeListener,
                                 
    // Use the music stream.
                                 
    AudioManager.STREAM_MUSIC,
                                 
    // Request permanent focus.
                                 
    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
       
    if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
       
    // Start playback.
    }
  • Focus의 변화에 따라 아래와 같이 대응한다.
    OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
       
    public void onAudioFocusChange(int focusChange) {
           
    if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT
               
    // Pause playback
           
    } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
               
    // Resume playback
           
    } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
                am
    .unregisterMediaButtonEventReceiver(RemoteControlReceiver);
                am
    .abandonAudioFocus(afChangeListener);
               
    // Stop playback
           
    }
       
    }
    };
  • Duck 상태에서는 아래와 같이 대응한다.
    OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
       
    public void onAudioFocusChange(int focusChange) {
           
    if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
               
    // Lower the volume
           
    } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
               
    // Raise it back to normal
           
    }
       
    }
    };


재생되는 오디오 기기에 대해

  • 현재 재생 가능한 기기를 알아보기 위해서는 아래와 같이 한다. (AudioManager의 메소드)

    if (isBluetoothA2dpOn()) {
       
    // Adjust output for Bluetooth.
    } else if (isSpeakerphoneOn()) {
       
    // Adjust output for Speakerphone.
    } else if (isWiredHeadsetOn()) {
       
    // Adjust output for headsets
    } else {
       
    // If audio plays and noone can hear it, is it still playing?
    }
  • 재생되던 기기의 변경이 일어났을 때 처리는 아래와 같이 한다. (특히, 이어폰을 빼거나 블루투스를 껐을때)
    private class NoisyAudioStreamReceiver extends BroadcastReceiver {
       
    @Override
       
    public void onReceive(Context context, Intent intent) {
           
    if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
               
    // Pause the playback
           
    }
       
    }
    }

    private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);

    private void startPlayback() {
        registerReceiver
    (myNoisyAudioStreamReceiver(), intentFilter);
    }

    private void stopPlayback() {
        unregisterReceiver
    (myNoisyAudioStreamReceiver);
    }

출처 : http://developer.android.com/

설정

트랙백

댓글