Android: MediaPlayer AUDIOFOCUS_LOSS & setOnErrorL

2020-03-25 15:01发布

I'm creating a music player app.

In that I am checking if my application loses AudioFocus then the playback will stop. But this is raising one issue that when I play a track - then stop it and - then play a track again, switch case AudioManager.AUDIOFOCUS_LOSS is getting called in which I've stopped the player as it is losing focus.

So my own app is losing focus to itself. Obviously, these were not my intentions. I wanted it to get called when some other music player requested focus.

private OnAudioFocusChangeListener focusChangeListener = new OnAudioFocusChangeListener() {
    @Override
    public void onAudioFocusChange(int focusChange) {
        switch (focusChange) {
        case AudioManager.AUDIOFOCUS_LOSS:

            if (mPlayer.isPlaying()) {
                stopPlayback();
            }
            break;
        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
            if (mPlayer.isPlaying()) {
                mPlayer.pause();
            }
            break;
        case AudioManager.AUDIOFOCUS_GAIN:
            if (!mPlayer.isPlaying()) {
                initiatePlayback();
            }
            break;
        }
    }
};

There is one more problem, Exception that I was getting is IllegalStateException.

This means when the code reaches inside case AudioManager.AUDIOFOCUS_LOSS, my musicplayer is in some erroneous state. So to check that, I registered an OnErrorListener using:

//Inside Service - onCreate() Method
mPlayer.setOnErrorListener(mErrorListener);

But this listener is never gets called. I'll appreteate any help.

2条回答
劫难
2楼-- · 2020-03-25 15:26

I had similar issue, I strongly suspect that your focusChangeListener is recreated somewhere in your program so you request focus on different instance of focusChangeListener. Are you defining it from a service or activity?

The idea is to maintain a single copy of your focusChangeListener that you pass to requestAudioFocus() and abandonAudioFocus(); otherwise the AudioManager will consider the request from different source, which can cause the app can lose focus to itself.

You should know that calling requestAudioFocus() on the same listener object many times does register it only once and calling abandonAudioFocus() one time is sufficient to release the audio focus.

Few suggestions that can solve your problem:

  • Try to define focusChangeListener as static object and see if help.

  • If your listener is registered in Activity, consider to move to a service so the listener can survive longer.

  • To debug this issue, it is very helpful to log the following ** whenever ** you request or abandon focus to ensure that you have, to ensure that you are dealing with the same instance:

    • Your focusChangeListener e.g. focusChangeListener.hashCode()
    • Current context object e.g. context.hashCode()
    • Current thread id e.g. Thread.currentThread().getId()

For example:

  Log.d(TAG, String.format("Request audio focus: thread id = %s, context = %s, listener = %s",Thread.currentThread().getId(),context.hashCode(),focusChangeListener hashCode())

Edit:

Using application context i.e. getApplicationContext() can solve the issue as well.

查看更多
神经病院院长
3楼-- · 2020-03-25 15:37

Unfortunately IllegalStateExceptions don't trigger the OnErrorListener call. You will have to try/catch around portions of your code for IllegalStateExceptions where they may be triggered.

查看更多
登录 后发表回答