Westporch
Westporch

Reputation: 817

Android audio focus (AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)

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

Answers (1)

Michael
Michael

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

Related Questions