❮
[Android][번역] 오디오 인터럽트 다루기
20180314
"적절하게" 오디오 인터럽트를 다루는 방법
당신의 앱이 아무리 좋아도 전화를 받을 때 오디오 재생이 멈추지 않았다면 유저는 싫어할 것이다. 기기는 정말 중요한 것을 재생하도록 내버려 두지 않을 것이므로, 그 유저는 전화를 끊고 나서야 지난 12분간 그 팟캐스트를 놓친 걸 발견하고 무슨 일이 일어났는지도 모를 것이다. 이건 전부 당신의 책임이다.
그러니,
오디오 포커스를 잃을 때는 오디오 재생을 중지하라. 오디오 포커스 문서에서는 한번에 딱 하나만 재생하는 것을 가정하고 있다. 이 뜻은 시스템이 현재 오디오를 재생하고 있고 관심 있는 앱을 추적할 방법이 필요하다는 뜻이다. 오디오 포커스는 소라 고동 역할을 수행함으로써 도움을 준다. — 그것을 잡고 있을 때에는 말을 할 수 있다. 그러나 시스템은 다른 누군가의 차례가 되면 그걸 다시 가져갈 것이다.
당신의 앱이 음악을 스트리밍하는 상황을 생각해보자. 유저는 대부분의 경우에 방해받지 않고 싶을 것이다.
- 만약 전화가 온다면, 유저는 분명히 음악이 계속 재생되는걸 원하지 않을 것이다. 그러니 시스템은 앱을 음소거로 만들것이고, 당신은 지금 일시적으로 오디오 포커스를 잃었다는 것을 인지해야만 하고 ( 전화가 끝나면 다시 돌아올 것입니다!) 기다리는 동안에 음악을 잠시 멈춰야 합니다.
- 만약 유저가 내비게이션의 지시를 따르고 있다면, 그 지시는 음악 소리보다 더 크게 들려야 합니다. 앱은 잠깐 앱의 소리를 줄임 ("ducking") 으로 대처할 수 있습니다. 아니면 지시가 끝날때까지 음악을 중지할 수도 있습니다.
- 만약 음악을 끝내고 다른 앱에 있는 팟캐스트를 재생하기로 한다면, 이건 오디오 포커스의 영구적인 제거를 의미하고 당신의 앱은 종료될 것입니다
오디오 포커스는 당신에게 이런 상황들을 알려줄 수 있는 소라 고동입니다!
다행히 이안 레이크의 BabbQ에서의 미디어 재생 대화에 오디오 초점이 상당히 철저하게 파괴되었기 때문에 이것을 확실히 확인해 보세요. 하지만 여기 오디오에 초점을 맞춘 변화에 대응하는 것에 대한 분석이 있습니다.
당신의 앱에 오디오 포커스를 다루기 위해서는
AudioManager 를 이용할 수 있습니다. 어떤 것을 재생할 준비가 됐을 때, 그저
요청(request)하기만 하면 됩니다. (재생이 끝나면
release하는 것을 꼭 기억하세요.) (역자 주 - requestAudioFocus, abandonAudioFocus)
오디오 포커스가 인정되면, 소라고둥을 잡고 재생하면 됩니다. 하지만 아까 말한대로 시스템은 일시적이든 영구적이든 오디오 포커스를 다시 가져갈 수 있습니다. 따라서 상태를 계속 파악하고 이런 변화에 대응하기 위해서 OnAudioFocusChangeListener 가 필요합니다! 아마도 그건 이런 모양일 것입니다:
AudioManager.OnAudioFocusChangeListener afChangeListener =
new AudioManager.OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
// 오디오 포커스를 일시적으로 빼앗겼기에 재생을 잠깐 멈춥니다.
// 하지만 곧 돌아올 것입니다.
// (예시. 통화)
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
// 오디오 포커스를 잃었기에 재생을 완전히 멈춥니다.
// (예시. 유저가 다른 오디오 재생 앱을 시작했을 때)
// Remember to unregister your controls/buttons here.
// And release the kra — Audio Focus!
// You’re done.
am.abandonAudioFocus(afChangeListener);
} else if (focusChange ==
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
// 다른 것이 재생되고 있기 때문에 소리를 줄입니다.
// (예시. 알림 또는 내비게이션의 지시)
// 오디오 재생에 따라서 멈추는 것이 더 나은 경우도 있습니다.
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
// 재생을 재개합니다, 오디오 포커스를 다시 얻었습니다!
// (예시. 통화가 끝났을때 또는 내비 지시가 끝났을 때)
// (만약 ducking과 볼륨을 줄이는 것으로 구현했다면.
// 여기에서 볼륨을 원래대로 돌려야 합니다.
}
}
};
자유롭게 복사하고 붙여넣으세요. 아니면 switch 문으로 바꾸고 인터넷에서 저를 조롱하시면 됩니다. 어떤 방법이든 오디오 포커스를 적절하게 사용하게 될 겁니다!
도움이 될지는 모르겠지만, 안드로이드 6.0 의 경우에는 LISTEN_CALL_STATE 는 더 이상 READ_PHONE_STATE permission 을 요구하지 않습니다. 하지만 다른 몇몇 전화 옵션들은 permission을 요구합니다. 음악을 정지하기만 하면 전화 사용 허가 여부를 묻는 잘못 쓰여진 코드를 원하지 않을 겁니다. 그건 끔찍합니다 .
롤리팝 이전의 기기에서도 오디오 포커스를 이용해야 한다는 걸 기억하세요. 전화 상태에만 반응한다는 건 다른 오디오 신호들을 놓치고 있을 지도 모른다는 겁니다. 내비게이션 지시나 다른 앱이 시작되는 경우를 생각해보세요. 당신의 앱은 당신의 유저를 위해 있는 것이지 앱을 삭제할 때까지 유저를 화나게 하라고 있는게 아닙니다.
그러니 미디어 재생을 올바른 방법으로 시도하세요. 오디오 포커스에 따라 사용자에게 원활한 환경을 만들어 주세요. 그래야 더 나은 앱을 만들 수 있습니다.