Reputation: 817
I used AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK but android system called AUDIOFOCUS_LOSS_TRANSIENT.
I don't know why system doesn't call AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK.
Normal operation is following
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK to
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
please give me some advice.
Thanks.
// MainActivity.java
package com.example.af_test;
import android.app.Activity;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private AudioManager am;
private MediaPlayer mp;
private MediaPlayer mp_alarm;
private String LOG = "Seo";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mp = MediaPlayer.create(this, R.raw.explosion);
mp_alarm = MediaPlayer.create(this, R.raw.caution); // test
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
am = (AudioManager) getSystemService(AUDIO_SERVICE);
int requestResult = am.requestAudioFocus(
mAudioFocusListener, AudioManager.STREAM_MUSIC,
//AudioManager.AUDIOFOCUS_GAIN);
//AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
if (requestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mp.start();
Log.d(LOG, "Successfull to request audioFocus listener");
}
else if(requestResult == AudioManager.AUDIOFOCUS_REQUEST_FAILED)
{
mp.stop();
//mp_alarm.stop();
}
else {
Log.d(LOG, "Failure to request focus listener");
}
//mp.start();
// am.abandonAudioFocus(mAudioFocusListener);
// Log.d(LOG, "Abandon focus");
}
});
// 동영상 재생이 완료된걸 알수있는 리스너
mp.setOnCompletionListener(new OnCompletionListener() {
// 동영상 재생이 완료된후 호출되는 메서드
public void onCompletion(MediaPlayer player) {
am.abandonAudioFocus(mAudioFocusListener);
}
});
}
@Override
// onDestroy()는 해당 Activity가 화면에서 사라진 후에 호출된다.
protected void onDestroy() {
mp.stop();
am.abandonAudioFocus(mAudioFocusListener);
Log.d(LOG, "Abandon focus");
super.onDestroy();
}
public void abandonAudioFocus() {
//Abandon audio focus
int result = am.abandonAudioFocus(mAudioFocusListener);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.d(LOG, "Audio focus abandoned");
} else {
Log.e(LOG, "Audio focus failed to abandon");
}
}
public void stop() {
mp.stop();
abandonAudioFocus();
}
private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
// AudioFocus is a new feature: focus updates are made verbose on
// purpose
switch (focusChange) {
case AudioManager.AUDIOFOCUS_LOSS:
mp.stop();
//stop();
Log.d(LOG, "AudioFocus: received AUDIOFOCUS_LOSS");
// mp.release();
// mp = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// if (mp.isPlaying())
mp.pause();
Log.d(LOG, "AudioFocus: received AUDIOFOCUS_LOSS_TRANSIENT");
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
mp.setVolume(0.5f, 0.5f);
Log.d(LOG, "AudioFocus: received AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
break;
case AudioManager.AUDIOFOCUS_GAIN:
mp.start();
mp.setVolume(1.0f, 1.0f);
Log.d(LOG, "AudioFocus: received AUDIOFOCUS_GAIN");
break;
default:
Log.e(LOG, "Unknown audio focus change code");
}
}
};
}
<!-- activity_main.xml -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<Button
android:id="@+id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Audio Focus Test" />
</RelativeLayout>
Logcat informations
08-05 16:46:00.115: I/AudioService(2429): AudioFocus requestAudioFocus() from 11622 focusChangeHint:3
08-05 16:46:00.115: V/CorePlayerService(20934): AudioFocus: received AUDIOFOCUS_LOSS_TRANSIENT
08-05 16:46:00.165: D/Seo(11622): Successfull to request audioFocus listener
08-05 16:46:03.400: I/AudioService(2429): AudioFocus abandonAudioFocus() from 11622
08-05 16:46:03.405: V/CorePlayerService(20934): AudioFocus: received AUDIOFOCUS_GAIN
08-05 16:46:03.435: I/AudioService(2429): AudioFocus requestAudioFocus() from 20934 focusChangeHint:1
Upvotes: 1
Views: 9336
Reputation: 58457
Your interpretation of how audio focus works seems to be slightly incorrect. When you lose audio focus you don't get a LOSS
based on the GAIN
that you requested earlier (e.g. requesting AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
does not mean you'll get a AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
when you lose audio focus).
Instead, the loss of audio focus is determined by what type of audio focus another app is requesting. So, for example, if some other app has requested and been granted AUDIOFOCUS_GAIN_TRANSIENT
, then your app will receive AUDIOFOCUS_LOSS_TRANSIENT
(or, in some cases, AUDIOFOCUS_LOSS
).
If you're interested in how this mapping from GAIN
to LOSS
is done, you can find it in FocusRequester.java in the Android source code.
Upvotes: 3