i have a question a android programming for media play code - android

When the media is already playing in the background and you want to play the media in another app, I want to stop the media that was playing and stop the media that was playing after receiving the signal from the existing app. In other words, I want to detect the signal to stop the existing media playback signal if there is another media playback signal.
I think it might be related to android AUDIOFOCUS_REQUEST_GRANTED by calling android requestAudioFocus (), please help.

from the documentation
read the documentation. it explains everything.
in OnAudioFocusChangeListener you can listen when another app has audio focus and you can respond to the changes.
for example:
AudioManager.OnAudioFocusChangeListener afChangeListener =
new AudioManager.OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
// Permanent loss of audio focus
// Pause playback immediately
mediaController.getTransportControls().pause();
// Wait 30 seconds before stopping playback
handler.postDelayed(delayedStopRunnable,
TimeUnit.SECONDS.toMillis(30));
}
else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
// Pause playback
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
// Lower the volume, keep playing
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
// Your app has been granted audio focus again
// Raise volume to normal, restart playback if necessary
}
}
};
let me know if you need more clarification

Related

How do I determine when Google maps is Speaking in Android

I'm trying to modify my application to pause audio playback when Google maps is announcing a turn by turn direction.
I've added the following code (shown below) to my application. The audio focus listener is called when applications like Pandora Radio or Spotify request audio focus in order to play music but it's not called when Google maps announces a turn by turn direction. Is there another intent I should be listening for in order to detect this behavior?
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.requestAudioFocus(new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(new AudioManager.OnAudioFocusChangeListener() {
#Override
public void onAudioFocusChange(int focusChange) {
// This is called by Pandora Radio and Spotify
Log.d("Focus change:", " Event is: " + focusChange);
}
}).build());
You will need AudioManager's AudioPlaybackCallback updates.
This only works on Android O and above.
To do this you have to access the audio manager -
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
And then add the listener like this -
Handler handler = new Handler();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
audioManager.registerAudioPlaybackCallback(new AudioManager.AudioPlaybackCallback() {
#Override
public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
super.onPlaybackConfigChanged(configs);
// This will be called when navigation audio state on google maps changes
Log.d("audio active", String.valueOf(audioManager.isMusicActive()));
}
}, handler);
}
The List<AudioPlaybackConfiguration> configs returned in the callback has a AudioAttribute object which contains a string describing the audio playing. For Google maps navigation the String constant value is USAGE_ASSISTANCE_NAVIGATION_GUIDANCE which you can compare to be sure that it is Google Maps announcing the navigation direction.
Programatically you can get it like this
// Loop through the configs to see the media's usage data
configs.get(0).getAudioAttributes().getUsage();
For Android O, the missing navigation duck focus change notifications were only received after I explicitly set my player's AudioAttributes and content type to speech (as I am playing podcast mp3 files, didn't test with other content types):
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
AudioAttributes.Builder aab = new AudioAttributes.Builder();
aab.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH);
aab.setUsage(USAGE_MEDIA);
player.setAudioAttributes(aab.build());
#Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
if (mPlayOnAudioFocus && !isPlaying()) {
play();
} else if (isPlaying()) {
setVolume(MEDIA_VOLUME_DEFAULT);
}
mPlayOnAudioFocus = false;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
setVolume(MEDIA_VOLUME_DUCK);
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
if (isPlaying()) {
mPlayOnAudioFocus = true;
pause();
}
break;
case AudioManager.AUDIOFOCUS_LOSS:
mAudioManager.abandonAudioFocus(this);
mPlayOnAudioFocus = false;
stop();
break;
}
}
}
The following code snippet contains an implementation of this interface for an app that plays audio. And it handles ducking for transient audio focus loss. It also handles audio focus change due to the user pausing playback, vs another app (like the Google Assistant) causing transient audio focus loss
does your app temporarily need audio focus (with the option to duck), since it needs to play an audio notification, or a turn by turn spoken direction, or it needs to record audio from the user for a short period of time? This is
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK.
Ducking vs pausing on transient audio focus loss
You can choose to pause playback or temporarily reduce the volume of your audio playback in the OnAudioFocusChangeListener, depending on what UX your app needs to deliver. Android O supports auto ducking, where the system will reduce the volume of your app automatically without you having to write any extra code. In your OnAudioFocusChangeListener, just ignore the AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK event.
In Android N and earlier, you have to implement ducking yourself (as shown in the code snippet above).
for Detail visit :https://medium.com/androiddevelopers/audio-focus-3-cdc09da9c122
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
added in API level 8
public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
Used to indicate a temporary request of audio focus, anticipated to last a short amount of time, and where it is acceptable for other audio applications to keep playing after having lowered their output level (also referred to as "ducking"). Examples of temporary changes are the playback of driving directions where playback of music in the background is acceptable.
You should use "AudioManager.AUDIOFOCUS_GAIN_TRANSIENT", according to the documentation:
AUDIOFOCUS_GAIN_TRANSIENT
Used to indicate a temporary gain or request of audio focus, anticipated to last a short amount of time. Examples of temporary changes are the playback of driving directions, or an event notification.

Android - How to change sound output while playing sound?

I have an app that plays a list of soundtracks. It works great, however changing the sound output to internal speakers or vice versa, has no effect. It stops the current one, and then plays the next on the new mode.
I've read in android documentation of MediaPlayer that I can't change the sound output using setAudioStreamType() method. So this is the problem, but can't find a solution!
Here's the code for the toggle when the track is playing:
if (this.audioManager.isSpeakerphoneOn() || this.getCurrent() == 1) {
this.audioManager.setMode(AudioManager.MODE_IN_CALL);
this.audioManager.setSpeakerphoneOn(false);
this.mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
} else if (this.getCurrent() != 0) {
this.audioManager.setMode(AudioManager.MODE_NORMAL);
this.audioManager.setSpeakerphoneOn(true);
this.mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
Thanks in advance!

How to stop Media Player when you have more that one sound being played?

My app is a music pad, which allows the user to create their own music by pressing buttons that will play a specific sound, and if the users presses more than one button there will be more sounds being played at the same time.
I want to stop all sounds when the onPause() gets called. But I realized that if I have more than one sound being played by the same Media player Object it only stops the last sound that was attributed to it, and the others stay on playing.
It would be very unpleasant for the user to receive a call and having my app sounds still on playing :p
Any help would be appreciated.
#Override
protected void onPause() {
super.onPause();
try {
while (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
}catch (IllegalStateException e){
//Do nothing
}
}
EDIT
I tried to implement SoundPool API but since my app is very dynamic (users can upload their samples and also record using mic). And I have everything already implemented and working well, it would be a mess to change it now to another API rather than MediaPlayer. Is there any way to stop all sounds that were attributed to the MediaPlayer object and that are currently being played? maybe accessing to some other classes and using other methods to stop all the sounds?
I would suggest you look into the SoundPool API. It looks like that would be well suited for your task. It allows you to preload sound files and play them independently.
The SoundPool class manages and plays audio resources for applications.
A SoundPool is a collection of samples that can be loaded into memory from a resource inside the APK or from a file in the file system. The SoundPool library uses the MediaPlayer service to decode the audio into a raw 16-bit PCM mono or stereo stream. This allows applications to ship with compressed streams without having to suffer the CPU load and latency of decompressing during playback.
After a few research and trial and error there is no way that I discovered to stop all sounds being played by the same MediaPlayer Object, you can only control the last sound being attributed to it, all the other will continue until they end or the app gets destroyed.
Ok so what I did was:
I created an object for each key sound of my music pad, and Override the onPause() with the following code:
#Override
protected void onPause() {
super.onPause();
if (mAudioManager.isMusicActive()){
for (MediaPlayer aMMediaPlayer : mMediaPlayer) {
if (aMMediaPlayer != null) {
try {
if (aMMediaPlayer.isPlaying()) {
aMMediaPlayer.stop();
aMMediaPlayer.release();
}
} catch (IllegalStateException e) {
//Do nothing
}
}
}
}
}

How to remove background Noise in Audio Track?

I am developing VOIP kind of application. Sending the voice is perfect but when i receive the same voice from the webserver, i am playing back that using AudioTrack API.
I am calling at.play() and at.write in a Thread so that i should get all the voice which is recorded and sent from the other device.
But, now the problem here i m facing is, if there is no voice than its still playing like some bullet sound, i mean there is a continuos background sound when i try to play .
I m using this following function in a Thread:
if (at != null) {
if (at.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
at.play();
} else {
if (playing == true) {
System.out.println("BEFORE WRITE");
at.write(playShortData, 0,
playShortData.length);
System.out.println("AFTER WRITE");
at.flush();
playing = false;
}
}
}
How can i remove the background noise if there no voice is send from other device.
I think its playing Junk value when none of them is speaking on other sides, its just sending junk values ..

Android - is it possible to find out which app has audiofocus?

There's an app on my phone that keeps taking audio focus, even when no sound is playing. I'm wondering as an app developer if I'd be able to inform the user which app it is, or if I can tell if my app has audio focus?
I strongly doubt that there is any public APIs can tell you which app having the focus at the moment.
You can keep track if your app has the audio focus by requesting it, e.g.:
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
boolean requestGranted = AudioManager.AUDIOFOCUS_REQUEST_GRANTED == audioManager.requestAudioFocus(listener, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if(requestGranted){
// you now has the audio focus
}
You should make sure to maintain a single instance of your listener when you request and abandon focus, see my answer here to troubleshoot common problems with audio focus
Here is an example of onAudioFocusChange():
#Override
public void onAudioFocusChange(int focus) {
switch (focus) {
case AudioManager.AUDIOFOCUS_LOSS:
Log.d(TAG,"AUDIOFOCUS_LOSS");
// stop and release your player
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
Log.d(TAG,"AUDIOFOCUS_LOSS_TRANSIENT");
// pause your player
break;
case AudioManager.AUDIOFOCUS_GAIN:
Log.d(TAG,"AUDIOFOCUS_GAIN");
// restore volume and resume player if needed
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
Log.d(TAG,"AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
// Lower volume
break;
}
}
Maybe this method does what you want:
AudioManager.isMusicActive()
http://developer.android.com/reference/android/media/AudioManager.html#isMusicActive%28%29

Categories

Resources