How to control Media Volume when a Bluetooth device is connected? - android

I have setted the StreamControlVolume in the OnCreate of my Activity in order to control Music/Media with volume buttons.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
But when I connect a Bluetooth device to my application and Sco is routed, the VolumeControlStream switches to bluetooth, I have tried to change the VolumeControlStream after the Sco is on, but it still changes Bluetooth volume when I press the volume buttons like in the image below:
I have tried to setControlStream right before the volume changes (overriding dispatchKeyEvent) but it didn't worked
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
setVolumeControlStream(AudioManager.STREAM_MUSIC);
default:
return super.dispatchKeyEvent(event);
}
}

Related

How to check if sound should be ducked?

When we loose audio focus due to AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK we should reduce sound volume, untile audiofocus will be restored to AudioManager.AUDIOFOCUS_GAIN. However, it is fired if we registered listener before event.
How to check if audio focus is in state AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK if we registered after AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK event?
AudioManager.OnAudioFocusChangeListener audiofocusListener =
new AudioManager.OnAudioFocusChangeListener() {
#Override public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN: {
}
break;
case AudioManager.AUDIOFOCUS_LOSS: {
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: {
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
}
break;
}
}
};
If I understand your question correctly, you want to know whether some other app is currently holding audio focus (and thus the audio output of your app should be ducked) before you actually have registered your audio focus listener.
If that's the case (some other app currently owns the audio focus), then your request for acquiring the audio focus will be denied, that is, your call to AudioManager.requestAudioFocus with audiofocusListener will return with AUDIOFOCUS_REQUEST_FAILED.

Amazon fire remote affecting background process

I have a media application for the Amazon Fire tv and tv stick. I have successfully captured the buttons and have customized the events accordingly.
Issue arises in the case when some other media app such as pandora is running in the background. When I fastforward,rewind etc in my app , even pandora gets changed in the process.Amazon has declined the app for the same reason.How do I get to set the focus of the remote in the current app only.
The following is my code for remote
#Override
public boolean onKeyDown(int keyCode, KeyEvent event){
boolean handled = false;
switch (keyCode){
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_DPAD_LEFT:
mPlayerView.seek((int)mPlayerView.getPosition()-3000);
handled = true;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
Log.e("right","pressed");
mPlayerView.seek((int)mPlayerView.getPosition()+3000);
handled = true;
break;
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
mPlayerView.seek((int)mPlayerView.getPosition()+60000);
handled=true;
break;
case KeyEvent.KEYCODE_MEDIA_REWIND:
mPlayerView.seek((int)mPlayerView.getPosition()-60000);
handled=true;
break;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
mPlayerView.play();
handled=true;
break;
case KeyEvent.KEYCODE_MENU:
subtitle=!subtitle;
if(subsexists){
if(subtitle) {
mPlayerView.setCurrentCaptions(1);
Toast.makeText(this,"Subtitles ON",Toast.LENGTH_LONG).show();
}
else {
mPlayerView.setCurrentCaptions(0);
Toast.makeText(this,"Subtitles OFF",Toast.LENGTH_LONG).show();
}
}
handled=true;
break;
}
return handled || super.onKeyDown(keyCode, event);
}
See this section of the FireTV Developer FAQ. Specifically you need to implement code to:
When app starts playing, request audio focus with AudioManager.requestAudioFocus()
If audio focus was granted, register a media button receiver with AudioManager.registerMediaButtonEventReceiver()
you also need to make sure that you gracefully give up control as well if another media player app has the users attention
Listen for the loss of audio focus with AudioManager.onAudioFocusChangeListener()
If your app loses audio focus, stop playback and unregister the media buttons with AudioManager.unregisterMediaButtonEventReceiver()

How to synchronize Mediaplayer with phone volume?

I noticed that regardless of the volume I set my phone, the sound for a button click in my app remains the same regardless, how can I synchronize it with the phone's system volume? Here's the code format I used
Mediaplayer buttonSoundClick;
buttonClickSound = MediaPlayer.create(this, R.raw.button_click_sound);
buttonClickSound.start();
buttonClickSound = MediaPlayer.create(this, R.raw.button_click_sound);
} private void prepareAsync() {
buttonClickSound.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
#Override
public void onClick(View v) {
//Button Click Sound
buttonClickSound.start();
Android has different volume levels for different stream types.
Override onKeyDown() and add the following code.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
return true;
default:
return false;
}
}
After this, try playing around with the stream types to get it right for your app. The stream types available are:
AudioManager.STREAM_MUSIC
AudioManager.STREAM_RING
AudioManager.STREAM_ALARM
AudioManager.STREAM_SYSTEM
AudioManager.STREAM_NOTIFICATION
OR
You could directly set the MediaPlayer stream type by using MediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
Buy, you must call this method before prepare() or prepareAsync() in order for the target stream type to become effective thereafter.

Handling "ducking" audioFocusChange with headphones

When Android receives an SMS the notification sends an AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK focus Change. I handle this by cutting the volume of the media player by 50%.
E.g.
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
// E.g. SMS
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK :
playerDuck(true);
break;
case AudioManager.AUDIOFOCUS_GAIN :
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT :
playerDuck(false);
playerResume();
break;
}
}
public synchronized void playerDuck(boolean duck) {
if (mediaPlayer != null) {
// Reduce the volume by half when ducking - otherwise play at full volume.
mediaPlayer.setVolume(duck ? 0.5f : 1.0f, duck ? 0.5f : 1.0f);
}
}
This works fine when listening to the mediaplayer through the device's speaker but if you plug the headphones in then, instead of reducing the volume temporarily, the mediaplayer is muted whilst the notification plays.
How should I be handling the change in audio focus differently when the headphones are plugged in?

Automatically silence the sound volume of Android Phone programmatically?

I'm developing an application that can turn off the sound of Android Phone automatically. How can I detect the volume of the sound and turn it off programmatically?
if (hour == myTime.getHour() && minute == myTime.getMinute()) {
if (Settings.getSetMyTime(this))
showNotificationAlarm(R.drawable.icon,
"It's time to work");
///so, i want to add the silet function here..help me, please?
}
Thanks in advance.
Have a look at the AudioManager, especially the getStreamVolume and setStreamVolume methods
EDIT
You can also use the method Nikola Despotoski provided with setRingerMode
A Service is a child of a Context so you can call directly getSystemService
See the updated code below (untested):
if (hour == myTime.getHour() && minute == myTime.getMinute()) {
if (Settings.getSetMyTime(this))
showNotificationAlarm(R.drawable.icon,"It's time to work");
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
am.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}
Register for AUDIO_SERVICE and then use the AudioManager to control the volume up/down or set profiles.
Or if you want to listen for changes in the Audio focus then make your Activity implements AudioManager.OnAudioFocusChangeListener. Override unimplemented method. Create switch that will take care of types of changes.
Like:
#Override
public void onAudioFocusChange(int focusChange) {
switch(focusChange)
{
case AudioManager.AUDIOFOCUS_GAIN:
//do something
break;
case AudioManager.AUDIOFOCUS_LOSS:
break;
}
Or if you want to listen for changes on the audio output, like unplugging the headphones (switching to phone speaker) use ACTION_AUDIO_BECOMING_NOISY sticky broadcast
http://developer.android.com/reference/android/media/AudioManager.html#ACTION_AUDIO_BECOMING_NOISY
http://developer.android.com/reference/android/media/AudioManager.html#RINGER_MODE_SILENT
See here
Edit: This is the solution. There was no need to handle AudioFocus but just set different ringer profile or adjusting volume
if (hour == myTime.getHour() && minute == myTime.getMinute()) {
if (Settings.getSetMyTime(this))
showNotificationAlarm(R.drawable.icon,
"It's time to work");
AudioManager audiomanager =(AudioManager)YourActivityName.this.getSystemService(Context.AUDIO_SERVICE);
audiomanager.setRingerMode(AudioManager.RINGER_MODE_SILENT); //or adjust volume here instead setting silent profile for the ringer
}

Categories

Resources