I have a video without any audio playing in my activity, so if my music player is playing and my app is opened the music stops. I was wondering if there is a way to not request the Audio focus and let the music play in the background even when my video is playing ? I have tried abandoning audio focus after starting the video but that doesn't seem to work either.
Here's the code I have tried till now -
String path = "android.resource://" + getPackageName() + "/" + R.raw.backgroundvideo;
mvvBackground.setVideoURI(Uri.parse(path));
mvvBackground.setMediaController(null);
mvvBackground.start();
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
am.abandonAudioFocus(new AudioManager.OnAudioFocusChangeListener() {
#Override
public void onAudioFocusChange(int focusChange) {
Log.d(LOG_TAG, "Audio focus changed!");
}
});
Any suggestions will be appreciated ! Thanks
I have not tried this, but according to the docs, for API level 26 and above you can use mVideoView.setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE) to achieve this behaviour.
For below that API level, there is a workaround mentioned here.
Related
At app launch, is it possible to detect if the device's audio player or another app is currently playing music?
You can use the AudioManager to achieve this with it's IsMusicActive property:
AudioManager manager = (AudioManager)Android.App.Application.Context.GetSystemService (Android.Content.Context.AudioService);
var audioDetails = "Audio is " + (manager.IsMusicActive ? "on" : "off");
I'm developing an android application. If we have the package name of an application, could we know whether an application is playing music or recording the voice or not? I have no idea how to do that. If someone has done it, could you please help me or give me the information about it?
Thank your for your help,
public class AudioManager {
/**
* Checks whether any music is active.
*
* #return true if any music tracks are active.
*/
public boolean isMusicActive() {
return AudioSystem.isStreamActive(STREAM_MUSIC, 0);
}
}
AudioManager is what you are looking for. You can check this response: https://stackoverflow.com/a/16252044/3743245 Also the official documentation: AudioManager
And a small example of how to use it:
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
// Request audio focus for playback
int result = am.requestAudioFocus(focusChangeListener,
// Use the music stream.
AudioManager.STREAM_MUSIC,
// Request permanent focus.
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// other app had stopped playing song now , so you can do your stuffs now .
}
Them you add the focusChangeListener listed in the link I've left you.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
1) In an android project, I have written a service that plays music at the background. The problem is when my application is playing music at the background and another application(music player) plays music, both the audios play simultaneously. I want to stop playing the music in my application, if any other app plays the music. How do I deal with this.?
This is how I solved the issue.
Implement OnAudioFocusChangeListener listener
Initialise AudioManager like
private AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
Request Audio focus
mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
#Overide the following method of OnAudioFocusChangeListener
public void onAudioFocusChange(int focusChange)
{
switch (focusChange)
{
case AudioManager.AUDIOFOCUS_GAIN:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
resumePlayer(); // Resume your media player here
break;
case AudioManager.AUDIOFOCUS_LOSS:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
pausePlayer();// Pause your media player here
break;
}
}
This concept is called audio focus in Android.
In broad terms, it means that only one app can have audio focus at one point in time, and that you should relinquish if it asked to (for example if a phone call arrives, or another app wants to play music, &c).
To do this, you need to register an OnAudioFocusChangeListener.
Basically, you must:
Request audio focus before starting playback.
Only start playback if you effectively obtain it.
Abandon focus when you stop playback.
Handle audio focus loss, either by lowering volume temporarily ("ducking") or stopping playback altogether.
Please check the Managing Audio Focus article in the Android documentation.
private boolean reqAudioFocus() {
boolean gotFocus = false;
int audioFocus = am.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (audioFocus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
gotFocus = true;
} else {
gotFocus = false;
}
return gotFocus;
}
This will request for audio focus when you start your application and other music app is already running .So this will stop the already running app and start yours.
if (reqAudioFocus()) {
mPlayer.prepareAsync();
}
paste this where you want to prepare your mediaplayer.
For the other way round that is your app should stop when other app is played
use
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
am.abandonAudioFocus(this);
mPlayer.stop();
}
}
where "am" is your AudioManager Instance.
Dont forget to implement AudioManager.OnAudioFocusChangeListener
I have some code that plays a small notification beep from an mp3 (included in res/raw) that works fine on regular Android devices (various 2.2 and up), which I am trying to also use on Google TV and it doesn't seem to do anything, no errors, just no sound.
What could I be doing wrong (this has to be something simple that I am missing?).
Here is the basic code I'm using:
private void beep() {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(null, AudioManager.STREAM_NOTIFICATION, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
try {
Log.d(App.LOG_TAG, "playing the damn beep ****************");
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.beep);
// tried with and without volume
///mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.setLooping(false);
mediaPlayer.start();
} catch (Exception e) {
Log.e("beep", "error: " + e.getMessage(), e);
}
} else {
Log.d(App.LOG_TAG, "could not gain audio focus");
}
}
(NOTE: In real life I don't recreate the MediaPlayer and AudioManager every time, but I tried just putting everything in one method for test purposes. This works fine on the regular Android emulator, and on regular Android [phone] devices, but plays no sound on GTV emulator or Logitech Revue -- even though it does get into the MediaPlayer block fine and logs that it's playing the beep.)
Did you enable Notification sound in Settings->Picture & sound ->Notification sounds->Sounds->Default ?
I had the same problem. For whatever reason, it looks like the files need to be in ogg format. I tried .mp3, and a few versions of .wav. Even the GTV dev docs (https://developers.google.com/tv/android/docs/gtv_media_formats#StandardFormats) say .mp3 is okay.
My HiSense Pulse Google TV only plays the files if they are .ogg files.
This online converter seems to work: http://media.io/
The Google Voice Search comes with a significant delay from the moment you call it via startActivityForResult() until its dialog box is displayed, ready to take your speech.
This requires the user to always look at the screen, waiting for the dialog box to be displayed, before speaking.
So I was thinking of generating an audible signal instead of the dialog box by implementing RecognitionListener and sounding a DTMF tone in onReadyForSpeech() as in the following snippet:
#Override
public void onReadyForSpeech(Bundle params) {
Log.d(LCTAG, "Called when the endpointer is ready for the user to start speaking.");
mToneGenerator.startTone(ToneGenerator.TONE_DTMF_1);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
Log.e(LCTAG, "InterruptedException while in Thread.sleep(50).");
e.printStackTrace();
} // SystemClock.sleep(50);
mToneGenerator.stopTone();
}
The tone sounds beautifully but... it is also "heard" by the microphone, arriving to the voice recognition service and always generating a recognition error ERROR_NO_MATCH.
Is there a way to work around this?
Here is a random idea, and it may very well not work.
Can you try disabling the microphone (maybe via AudioManager.setMicrophoneMute) while the tone is played?
Here's my code that's working for me, put into the onReadyForSpeech() callback of the RecognitionListener.
private void playSpeechReadyTone(){
audioManager.setMicrophoneMute(true);
MediaPlayer mediaPlayer = MediaPlayer.create(JarvisService.this, R.raw.doublebeep);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer arg0) {
audioManager.setMicrophoneMute(false);
}
});
mediaPlayer.start();
}
I'm afraid that there isn't an easy&clean way to do that. As srf appointed, you shouldn't rely on AudioManager.setMicrophoneMute(boolean), so, AFAIK, the possibles are:
Play an audio file before call SpeechRecognizer.startListening(intent):
final MediaPlayer mediaPlayer = MediaPlayer.create(JarvisService.this, R.raw.doublebeep);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer player) {
player.release();
// Safety start Speech Recognizer
mSpeechRecognizer.startListening(getSpeechRecognizerIntent());
}
});
mediaPlayer.start();
However, this solution has a problem... If may receive an RecognitionListener.onError(int error) before RecognitionListener.onReadyForSpeech being called and, in that case, you are still playing a beep sound every time (this will happen, for example, if you are not connected to the Internet and Speech Recognition is configured to work online)!
Besides, you should manage the case of cancelling the speech recognition process during audio (doublebeep) play.
Play the audio in the onReadyForSpeech callback (read original question) but use RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS with an appropriate value. In my case, my beep sound is really short (1 second max) and I set RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS to 4/5 seconds.
Also note that, as Google doc says:
Note also that certain values may cause undesired or unexpected results - use judiciously! Additionally, depending on the recognizer implementation, these values may have no effect.