I'm playing some music from a service with Androids MediaPlayer. When the music is playing, the music volume can be changed by the volume rocker keys. However I don't want that the user can change the music volume during playback.
How can this be done?
It is possible when getting the keydown event and returning true, but that only works when the app is on top. Since I play the music from a service, it is also played when the screen is off or the app in background, so the volume can still be changed.
Another idea I had is to call
setVolumeControlStream( AudioManager.STREAM_RING );
after having started playing the music, but I can't call this from a service but only from an activity...
Or is it possible to play the music on another stream (Ring or alarm), but let the volume rocker still change the music stream?
Any ideas?
'You cannot intercept the key while your application is in background, but instead of listening to the KeyPress itself. You can register a ContentObserver'
Is there a broadcast action for volume changes?
Since I haven't found another way to do it, I check in a timer about 5 times per second if the volume has been changed. If it has, I change it back.
This is a really ugly solution, but it works and if there is no other way to do it, I have to leave it like this.
The only really horrible thing is that the volume dialog shows up when you press the volume rocker. Is there a way to disable the volume dialog?
Or do you know a better solution?
Related
I use android.media.MediaPlayer to play some sounds in my app, but when i press the physical volume button, it only changes the system volume (ringtone volume). I searched in google but i haven't had any idea yet.
I use android.media.MediaPlayer not Audiomanger.
Call the following right before you start playing music
setVolumeControlStream(AudioManager.STREAM_MUSIC);
and call the following after you finish
setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
This makes your volume rocker control all music streams and then resets it to default behavior (depends on what's happening).
Don't forget to call myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC) before myMediaPlayer.prepare(). Replace STREAM_MUSIC in both calls with some other value if it fits the played sound better. This makes the music you play conform to the music volume set in system, which is now controlled by the volume rocker.
Source:
http://developer.android.com/training/managing-audio/volume-playback.html
http://developer.android.com/reference/android/media/MediaPlayer.html#setAudioStreamType(int)
I want to play music with AudioTrack even if the media volume of the device is 0.
In my app, I want to have a SeekBar for the media volume (maybe if other music runs in the background) and one other SeekBar for the music of my app.
Until now, I can change the media volume. But then the music of my app is also silent..
How can I do that?
I think there is Six Different Streams of Sound in Android for Playing Different Types of Sounds
The first step to creating a predictable audio experience is understanding which audio stream your app will use.
Android maintains a separate audio stream for playing
music,
alarms,
notifications,
the incoming call ringer,
system sounds,
in-call volume,
and DTMF tones.
This is done primarily to allow users to control the volume of each stream independently.
Use Hardware Volume Keys to Control Your App’s Audio Volume
By default, pressing the volume controls modify the volume of the active audio stream. If your app isn't currently playing anything, hitting the volume keys adjusts the ringer volume.
If you've got a game or music app, then chances are good that when the user hits the volume keys they want to control the volume of the game or music, even if they’re currently between songs or there’s no music in the current game location.
You may be tempted to try and listen for volume key presses and modify the volume of your audio stream that way. Resist the urge. Android provides the handy setVolumeControlStream() method to direct volume key presses to the audio stream you specify.
Having identified the audio stream your application will be using, you should set it as the volume stream target. You should make this call early in your app’s lifecycle—because you only need to call it once during the activity lifecycle, you should typically call it within the onCreate() method (of the Activity or Fragment that controls your media). This ensures that whenever your app is visible, the volume controls function as the user expects.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
From this point onwards, pressing the volume keys on the device affect the audio stream you specify (in this case “music”) whenever the target activity or fragment is visible.
Thanks for your answers.
Now I use "AudioTrack(AudioManager.STREAM_SYSTEM, (...))" and it's working good.
Maybe it's not the best method but by now, it's working.
I'm writing an Android music player, and is stuck on audio focus issue.
It seems like audio focus mainly affects media button receiving, but after reading the document I have no idea about when to gain and give up focus.
My music app will run in background, and need to detect play/pause button every time. That is, even when my app is not running, a user should be able to press headset's play button and start music.
It seems I should never give up audio focus, so why should I implement it?
Does anyone know practically how audio focus should be used? Thank you!
It seems like audio focus mainly affects media button receiving, but
after reading the document I have no idea about when to gain and give
up focus.
They both are separate functionalities, and thus have separate listeners. You may have audio focus taken away from you but you may still choose to respond to play pause hardware keys
That is, even when my app is not running, a user should be able to
press headset's play button and start music.
I am assuming that you meant by the above line is that you are still playing music but not showing an activity. To keep listening to hardware button press, dont unregister your media button receiver(dont call audioManager.unregisterMediaButtonEventReceiver(receiver) yet).
It seems I should never give up audio focus, so why should I implement
it?
you dont give up the focus , it gets taken from you. To handle that gracefully you have AudioFocus listener. For ex, consider an incoming phone call. Would you still like to continue playing your music?
I play a song in background, and the screen is off now. I press the volume key, the volume of the music stream changes. How can it happen? I have searched for a long time for a solution about how to detect the volume keys press event when screen off, but I don't know how to solve the problem so far.
you need a BroadcastReceiver that listens to the according broadcasts. see a similar question here.
If you wish to control the volume of audio played through your app, make use of setVolumeControlStream() method. It directs volume key presses to the audio stream you specify.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
Is it possible to register a listener to listen for changes in the volume level of the music stream in Android?
I'm displaying the actual volume in a SeekBar and I would like to change the seekbar if the user changes the volume with the hardware volume keys. At the moment the correct volume is displayed until the user changes the volume with hardware keys.
This is not a perfect answer but a hack:
android.media.VOLUME_CHANGED_ACTION
I found above action in native logs while changing volume via hard volume key.
01-25 16:11:24.015: DEBUG/VolumePanel(189): onVolumeChanged(streamType: 2, flags: 4)
01-25 16:11:24.015: DEBUG/BluetoothA2dpService(189): Received intent with action: android.media.VOLUME_CHANGED_ACTION
so go ahead and register BroadcastReceiver with action "android.media.VOLUME_CHANGED_ACTION" if you don't have any other solution.
Other way of doing is;
Taking over the volume key on Android .
One option would be to use registerMediaButtonEventReceiver and have your application handle the hardware keys. You could adjust the volume seekbar in your app and use AudioManager to adjust the volume.
Another possibility would be to create a service in your app that runs in the background and periodically checks the volume and adjusts your seekbar accordingly.
You can display the volume by accessing the current volume from AudioManger if your app is currently in focus. Otherwise, there is no concrete way (official way using api) of doing this.
Android recommends letting the system do all of this for you by calling setVolumeControlStream(). This will bring up a volume seekbar for the audio stream that your app is using whenever the user tries to adjust the volume with their hardware buttons.
"You may be tempted to try and listen for volume key presses and modify the volume of your audio stream that way. Resist the urge. Android provides the handy setVolumeControlStream() method to direct volume key presses to the audio stream you specify.
Having identified the audio stream your application will be using, you should set it as the volume stream target. You should make this call early in your app’s lifecycle—because you only need to call it once during the activity lifecycle, you should typically call it within the onCreate() method (of the Activity or Fragment that controls your media). This ensures that whenever your app is visible, the volume controls function as the user expects.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
From this point onwards, pressing the volume keys on the device affect the audio stream you specify (in this case “music”) whenever the target activity or fragment is visible."
From: http://developer.android.com/training/managing-audio/volume-playback.html
I've faced a similar issue.
The app should show a volume off indicator in case of Media Sound has turned off during the video playback. This approach handles cases when the user changes Media level by swipe too.
So, wrote a simple Rx wrapper for ContentObserver which observes Media Sound level directly ))
Gist link here