I'm developing a game. I need a button to turn on and off game sounds.
In my app, I play background music which I want to be muted upon clicking a button. Here's my code:
AudioManager aManager = (AudioManager)getSystemService(AUDIO_SERVICE);
if (aManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
aManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
} else {
aManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
When I debug, the conditions are right but nothing happens! The sound is never turned off!
Check for method "isVolumeFixed()". If true, your device can't have it's sound changed. Some devices have a policy about that.
Related
I received the following feedback when submitting an app for Android Auto:
Your app does not support all of the required voice commands. Volume
doesn't reduce when voice command is initiated on the Android Auto.
I take this to mean that the app should reduce playback volume (it's a media player app) when the user presses the Speak/Mic button in the Android Auto UI (or also if they scream "Ok, Google" over the sound of their music, I suppose).
I guess the other possible interpretation is that there are voice commands for raising/lowering the volume that need to be supported, but that seems...unlikely. And I'm not seeing any such API hooks documented anywhere.
So I assume it's the former case, and I need to reduce the volume when voice recognition starts.
To do that it seems like I'd need to receive a notification of that event (and preferably, also a notification of when voice recognition has ended). Is there a boradcast intent or other way to trap this in my app so that I can reduce the media playback volume while the user is trying to say things?
Found the solution. What the app needs to listen to are audio focus change events, like:
#Override
public void onAudioFocusChange(int focusChange) {
AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
if (focusChange == AudioManager.AUDIOFOCUS_LOSS |+ focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
pause();
shouldPlayOnFocus = true;
}
else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
if (! isPlaying()) {
return;
}
//reduce the playback volume
}
else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
if (! isPlaying() && shouldPlayOnFocus) {
start();
shouldPlayOnFocus = false;
}
//restore stream volume if we reduced it earlier
}
}
This is covered in the reference documentation, here:
https://developer.android.com/reference/android/media/AudioManager.OnAudioFocusChangeListener.html
Android Auto triggers a transient loss of audio focus event (AUDIOFOCUS_LOSS_TRANSIENT) whenever the 'Speak' button is pressed.
When my character crosses a finish line, I play a "win" sound. I have an AudioSource object to which I simply call PlayOneShot and pass it my AudioClip as:
public void PlayWon() {
if (GameData.Data.Settings.SoundsOn) {
AudioSource audio = GetComponent<AudioSource>();
audio.Stop();
audio.PlayOneShot(WinSound);
}
}
My settings for the AudioSource are this:
and the object where this is attached to is loaded in a Loader scene which is never destroyed. I ensure this by calling:
DontDestroyOnLoad(this);
on Awake.
My sound plays fine on iOS, iPhone and iPads. But when testing on my Samsung Galaxy Tab S, the sound plays and then pauses whilst the interstitial advert is displayed and then when dismissed, the sound carries on. I am using Chartboost and Admob and use the basic invoke:
if (Chartboost.hasInterstitial(CBLocation.LevelComplete)) {
Debug.Log("Showing CB Ad");
Chartboost.showInterstitial(CBLocation.LevelComplete);
}
else if (_admobInterstitial.IsLoaded()) {
Debug.Log("Showing Admob Ad");
_admobInterstitial.Show();
}
else {
Debug.Log("Neither cached, trying CB again");
Chartboost.cacheInterstitial(CBLocation.LevelComplete);
Chartboost.showInterstitial(CBLocation.LevelComplete);
}
Any ideas why my sounds cut out on this device? I don't have another Android device to test it on but I'm assuming it's an Android related problem. The sound cuts out on both Chartboost and Admob.
Thanks
You can use a coroutine for playing the sound. When the coroutine is finished, you can show ads.
private IEnumerator PlaySoundAndShowAd()
{
//play sound
yield return new WaitForSeconds(1.0f)
//show ads or do something.
}
I have an app with an integrated music player. I don't want the music to be interrupted by incoming calls.
I use following function for that:
public static void updateDoNotDisturbMode(boolean enabled, boolean checkPrefs)
{
...
AudioManager audioManager = ((AudioManager) MainApp.get().getSystemService(Context.AUDIO_SERVICE));
NotificationManager notificationManager = (NotificationManager) MainApp.get().getSystemService(Context.NOTIFICATION_SERVICE);
// audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!enabled)
{
audioManager.setStreamSolo(AudioManager.STREAM_MUSIC, false);
audioManager.setStreamMute(AudioManager.STREAM_VOICE_CALL, false);
audioManager.setStreamMute(AudioManager.STREAM_RING, false);
audioManager.setStreamMute(AudioManager.STREAM_NOTIFICATION, false);
...
}
else
{
audioManager.setStreamSolo(AudioManager.STREAM_MUSIC, true);
audioManager.setStreamMute(AudioManager.STREAM_VOICE_CALL, true);
audioManager.setStreamMute(AudioManager.STREAM_RING, true);
audioManager.setStreamMute(AudioManager.STREAM_NOTIFICATION, true);
...
}
}
what works
silent phone if no headphones are connected
internal music player does play on without interruption if someone calls
so without headphones connected, everything works perfectly fine
what does not work
if headphones are connected, the standard beep sound is interrupting my music player and is played in the headphones
How can I avoid that incoming calls are interrupting my music player even if headphones are connected?
TARGET SDK
Only 4.2 and upwarts... (including 5)
What do you mean integrated music player? Can you change code of music app?
A player stops playing because it listens to PhoneStateChanges - void onCallEvent(int state, String number);
If you can change code of the player you should check is mute mode on within this method - if yes then do not stop playback.
If you can't change the code of player - you can use advanced player with preferences of audio focus. For example poweramp has such option. Set Settings/Audio/Audio Focus/Pause in Call to false (it works, tested right now). But you should change it manually all the time.
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/