Android: Error in requestAudioFocus ()

0

Create this class to play a sound file on android: link

The problem is that when running this application on my cell phone it stops instantly. When reviewing the logcat it appears this error.

Using the android studio debugger I was able to trace the error to line 52:

int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener, AudioManager .STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

Investigate the requestAudioFocus function and try to apply it as the google documentation says so modify the activity to match the documentation: link

Now the error occurs on line 58:

AudioAttributes playbackAttributes = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_GAME)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .build();

Note: Android studio showed the error " Call requires API level 26 (current min is 15) " so I had to add " @TargetApi (Build .VERSION_CODES.O) "on line 50.

In the logcat the error appears when running this version of the activity.

The question is: What is the correct way to use the requestAudioFocus () function?

Note: The Android version of the cell phone I am using to test the application is 4.2.2 and according to Google Documentation The API level it uses is 17 (JELLY_BEAN_MR1)

Note 2: The app is "inspired" by this repository . In case you want to run this application you should modify the file build.gradle and add the " google () " function on line 18.

    
asked by MahaSaka 27.05.2018 в 18:30
source

1 answer

3

About the error that occurred while implementing this code :

  

java.lang.NullPointerException

Occurred because mAudioManager was not initialized to use the .requestAudioFocus method.

You must initialize it to mAudioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); reason why in the updated code it no longer explodes in that part.

About the error in the code:

AudioAttributes playbackAttributes = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_GAME)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .build();

AudioAttributes should only be used in versions with a min sdk marked in API >= 21 So if you try to run that block of code in a lower version, it will cause you the exception:

  

java.lang.ClassNotFoundException: Did not find class   "android.media.AudioAttributes $ Builder"

The solution here is to implement both ways by marking the code in a version or the method with the annotation @RequiresApi.

For example, you must call to play the audio for the different versions:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) 
{
    // Aqui debes hacerlo con AudioAttributes
    PlayAudioWithAttributes(R.raw.color_red);
} 
else
{
    // Aqui tienes que hacerlo de la otra forma, sin audio Attributes
    PlayAudioWithoutAttributes(R.raw.color_red);
}

// Para versiones API 21+
@TargetApi(Build.VERSION_CODES.O)
public void PlayAudioWithAttributes(int audioResourceID) {

    //Create and setup the media player for the audio resource.
    mMediaPlayer = MediaPlayer.create(this, audioResourceID);

    mAudioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);

    AudioAttributes playbackAttributes = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_GAME)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .build();

    AudioFocusRequest focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
            .setAudioAttributes(playbackAttributes)
            .setAcceptsDelayedFocusGain(true)
            .setOnAudioFocusChangeListener(mOnAudioFocusChangeListener)
            .build();

    //Request audio focus in order to play an audio file. The app needs to play a short audio file
    //so we will request AUDIOFOCUS_GAIN_TRANSIENT
    int result = mAudioManager.requestAudioFocus(focusRequest);

    if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        //Start the audio file
        mMediaPlayer.start();
    }
}


@TargetApi(Build.VERSION_CODES.O)
public void PlayAudioWithoutAttributes(int audioResourceID) {
   // Aqui debes poner el codigo de como se hacia antes
}

For the old version (API < 21) that is the method PlayAudioWithoutAttributes , you can review this code , which is the correct way to implement it. According to the documentation, after making the audio focus request, you must leave it. Keep in mind, that this code uses a BroadcastReceiver, so you would only be interested in the part related to the requestAudioFocus and obviously you will discard all the code related to the Broadcast. Good luck.

    
answered by 25.06.2018 / 18:06
source