¿Cómo gestionar el enfoque de audio y el audio que se vuelve ruidoso en Android? | Por Devfardeen | Diciembre de 2021
Los dispositivos Android son potentes y pueden reproducir varios sonidos a la vez desde la fuente de salida: el altavoz. Sin embargo, esto puede causar una gran confusión, por lo que Android prioriza diferentes audios 1. La urgencia de reproducirlo y 2. Lo que requiere los últimos recursos de altavoces.
Al crear una aplicación de Android, para obtener una mejor experiencia de usuario, debemos preguntar al sistema antes de reproducir audio. Este código difiere según la versión de Android:
* Android 12 (API 31) o superior: El sistema gestiona el enfoque de audio. No necesitamos escribir código adicional.
* Android 8.0 (API nivel 26) a Android 11 (API 31): El sistema no administra el enfoque de audio, pero incluye algunos cambios introducidos desde Android 8.0 (nivel de API 26).
- Paso 1: Defina AudioManager.OnAudioFocusChangeListener antes del método onCreate ().
AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_GAIN){
playMusic();
}else if(focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
pauseMusic();
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
pauseMusic();
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
playMusic();
}
}
};
- Paso 2: declare Audio Manager en el método onCreate () y obtenga los servicios del sistema
AudioManager audioManger = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- Paso 3: establecer propiedades de audio
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
- Paso 4: establecer atributos en la clase de solicitud de enfoque.
AudioFocusRequest focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributes)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(audioFocusChangeListener)
.build();
- Paso 5: Solicite el enfoque de audio y almacene su valor
int result = audioManger.requestAudioFocus(focusRequest);
- Paso 6: si se aprueba la solicitud, se reproduce el audio.
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mPlayer.start();
}
* Android 7 (nivel de API 25) o inferior: El enfoque de audio no lo gestiona el sistema, sino que lo utiliza la aplicación. requestAudioFocus()
y abandonAudioFocus()
.
int result = audioManger.requestAudioFocus(audioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);//play audio if requested is granted
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mPlayer.start();
}
Nota: -Aunque este código es preciso, fácil de entender y admite niveles de API más bajos, ha quedado obsoleto. (Interrumpido)
¿Alguna vez te has preguntado cómo desconectar los auriculares y pausar el reproductor de música? Este no es el comportamiento predeterminado. Los desarrolladores de Android agregaron esta función a la aplicación.
Así es como se implementa:
- Paso 1: declare el receptor de transmisión (y el filtro de intención) para detectar la separación de los auriculares.
- Paso 2: Registre el receptor de transmisión cuando comience a reproducir audio.
Registre el receptor antes de reproducir audio:
registerReceiver(audioBecomingNoisy, noisyFilter);
mPlayer.play();
- Paso 3: anule el registro del receptor de transmisión inmediatamente después de pausar el audio.
Anule el registro del receptor cuando el audio finalice o esté en pausa.
mPlayer.pause();
unregisterReceiver(audioBecomingNoisy);
Incluya Audio-Focus y Audio-Becoming-Noisy en el archivo de clase Java:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.media.MediaPlayer;import android.widget.ImageButton;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;public final class MainActivity extends AppCompatActivity {
//Button and TextView declaration
MediaPlayer mPlayer;
ImageButton playButton;//Attributes to Manage Audio Focus
AudioManager audioManger;
AudioFocusRequest focusRequest;
AudioAttributes audioAttributes;//Implemention of Listener class to Monitor change in Audio Focus
AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_GAIN){
playMusic();
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
pauseMusic();
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS){
pauseMusic();
releaseAudio();
}
}
};//IntentFilter and Class Declaration to Control Noisy Audio
private IntentFilter noisyFilter;
private AudioBecomingNoisy audioBecomingNoisy;private class AudioBecomingNoisy extends BroadcastReceiver {
@Override
@RequiresApi(api = Build.VERSION_CODES.O)
public void onReceive(Context context, Intent intent) {
pauseMusic();
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//Assigning Audio to Media Player Class
mPlayer = MediaPlayer.create(getApplicationContext(), R.raw.ringtone);//declaring audioManager and Intent Filter
audioManger = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
noisyFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
audioBecomingNoisy = new AudioBecomingNoisy();//Button Declaration && Definition
playButton = findViewById(R.id.play_button);//Play Button Function
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mPlayer == null) {
mPlayer = MediaPlayer.create(getApplicationContext(), R.raw.ringtone);
}
if (mPlayer.isPlaying()) {
pauseMusic();
audioManger.abandonAudioFocus(audioFocusChangeListener);
} else {
playMusic();
}
}
});//On Completion of audio set reset and pause the audio
//Function to pause Music
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
pauseMusic();
releaseAudio();
}
});
}
void pauseMusic() {
mPlayer.pause();
updateSeekbarHandler.removeCallbacks(updateSeekbar);
playButton.setImageResource(R.mipmap.play);
//unregistering Broadcast receiver
unregisterReceiver(audioBecomingNoisy);
}//Release Media player
void releaseAudio() {
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
audioManger.abandonAudioFocus(audioFocusChangeListener);
}
}@RequiresApi(api = Build.VERSION_CODES.O)
void playMusic() {//registering Broadcaset receiver;
int result = audioManger.requestAudioFocus(focusRequest);
registerReceiver(audioBecomingNoisy, noisyFilter);
audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributes)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(audioFocusChangeListener)
.build();if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mPlayer.start();
}
}
Si tiene alguna pregunta, no dude en preguntarme @https://twitter.com/dev_fardeen
Referirse a: