Search code examples
javaaudioandroid-audiomanagerimplementschangelistener

Android AudioFocus onAudioFocusChange not listening for changes


I have been building a MediaPlayer Application, I've been trying to get my Mediaplayer Application to handle AudioFocusChange events. However, It appears no matter how I structure my code I will not listen for AudioFocusChange events and will continue playing over the top of other apps. Everything works except for when I click the play button in my app, it just plays the music on top of the other music app without pausing it. I tried

public void play() {
Intent("com.android.music.musicservicecommand");
        i.putExtra("command", "pause");
        MainActivity.this.sendBroadcast(i);
        int requestAudioFocus = AM.requestAudioFocus(afChangeListener, AudioManager.AUDIOFOCUS_GAIN, AudioManager.STREAM_MUSIC);
        if (requestAudioFocus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
            Toast.makeText(this, "Focus Granted", Toast.LENGTH_SHORT).show();
            if (!mediaPlayer.isPlaying() || mediaPlayer == null) {
                mediaPlayer.start();
                handler.removeCallbacks(moveSeekBarThread);
                handler.postDelayed(moveSeekBarThread, 300);
            }
        } else {
            Toast.makeText(this, "Focus Not Granted", Toast.LENGTH_LONG).show();
            return;
        }
    }

at the top of my play() method, however it still plays the other apps music on top of that one.

So far I have:

public class MainActivity extends AppCompatActivity implements             
AudioManager.OnAudioFocusChangeListener {

...

}

Followed By the listener block:

@Override
    public void onAudioFocusChange(int focusChange) {
        switch (focusChange) {
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                Toast.makeText(this, "FOCUS LOSS TRANSIENT", Toast.LENGTH_SHORT).show();
                pause();
                break;
            case AudioManager.AUDIOFOCUS_LOSS:
                pause();
                Toast.makeText(this, "FOCUS LOST", Toast.LENGTH_SHORT).show();
                break;
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
                Intent i = new Intent("com.android.music.musicservicecommand");
                i.putExtra("command", "pause");
                MainActivity.this.sendBroadcast(i);
                AM.setStreamVolume(AudioManager.STREAM_MUSIC, AM.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
                play();
            case AudioManager.AUDIOFOCUS_REQUEST_FAILED:
                stop();
                break;
            case AudioManager.AUDIOFOCUS_REQUEST_GRANTED:
                Intent iARG = new Intent("com.android.music.musicservicecommand");
                iARG.putExtra("command", "pause");
                MainActivity.this.sendBroadcast(iARG);
                AM.setStreamVolume(AudioManager.STREAM_MUSIC, AM.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
                play();
                break;
        }
    }

I have also tried implementation outside of the class declaration and designating an

AudioManager.OnAudioFocusChangeListener = new onAudioFocusChangeListener(){
public void onAudioFocusChange(int focusChange){
...
}

as a global function, however, that was also not listening for focusChange's

Toasts were implemented into each switch case to notify me of when Focus state had been changed but I never see any notifications from them. I also tried putting in the method:

int requestAudioFocus = AM.requestAudioFocus(null, AudioManager.AUDIOFOCUS_GAIN, AudioManager.STREAM_MUSIC);
        if (requestAudioFocus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
            Intent i = new Intent("com.android.music.musicservicecommand");
            i.putExtra("command", "pause");
            MainActivity.this.sendBroadcast(i);
}

However it only stops music in another app from playing once. I have a feeling I've overlooked something simple, I just cannot get it to work.


Solution

  • This was a simple mistake, instead of instantiating 'this' (instance) for the listener I was using an alternative listener I had previously defined but had forgotten to delete. Since the listener was implemented in the MainActivity:

    public class MainActivity extends AppCompatActivity implements AudioManager.OnAudioFocusChangeListener {
    
    AM.requestAudioFocus(afChangeListener <-- should have been 'this',
                    // Use the music stream.
                    AudioManager.STREAM_MUSIC,
                    // Request permanent focus.
                    AudioManager.AUDIOFOCUS_GAIN);
    

    requestAudioFocus() was declared incorrectly.

    The switch case for focus change was written correctly:

    @Override
        public void onAudioFocusChange(int focusChange) {
            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    Toast.makeText(this, "FOCUS LOSS TRANSIENT", Toast.LENGTH_SHORT).show();
                    pause();
                    break;
                case AudioManager.AUDIOFOCUS_LOSS:
                    pause();
                    Toast.makeText(this, "FOCUS LOST", Toast.LENGTH_SHORT).show();
                    break;
                case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
                    Intent i = new Intent("com.android.music.musicservicecommand");
                    i.putExtra("command", "pause");
                    MainActivity.this.sendBroadcast(i);
                    AM.setStreamVolume(AudioManager.STREAM_MUSIC, AM.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
                    play();
                case AudioManager.AUDIOFOCUS_REQUEST_FAILED:
                    stop();
                    break;
                case AudioManager.AUDIOFOCUS_REQUEST_GRANTED:
                    Intent iARG = new Intent("com.android.music.musicservicecommand");
                    iARG.putExtra("command", "pause");
                    MainActivity.this.sendBroadcast(iARG);
                    AM.setStreamVolume(AudioManager.STREAM_MUSIC, AM.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
                    play();
                    break;
            }
        }
    

    With the implementation at MainActivity written correctly as well:

    public class MainActivity extends AppCompatActivity implements AudioManager.OnAudioFocusChangeListener