Set the volume control stream from a service on Android - android

I'm working on a music app which consists in a Service playing music while other apps are running.
In order to enjoy the music and only the music, the Service mutes all the other apps. In order to do that, it mutes STREAM_MUSIC and play music over STREAM_VOICE_CALL (found that solution to mute other apps here)
As the Service uses STREAM_VOICE_CALL to play music, what I'm trying to find is a way to make the volume buttons control this stream when a sound is playing.
What I already tried:
setVolumeControlStream: only works in Activities
Capturing volume keys pressed events: Services do not receive such events (source)
audioManager.setMode(AudioManager.MODE_IN_CALL) : does not work in my case. Plus, the SDK documentation states that this "mode should only be used by the telephony application when it places a phone call".
At this point, I'm out of options and any help would be appreciated. Thanks!

I would personally not suggest you to STREAM_VOICE_CALL as it is meant to be recommended to use it for Voice calls as compared to media playback. Using this may prevent you from using features exposed by Android for media playback.
Having said this & taking into consideration your use-case, I think you need to look for changing 'call volume' level as compared to 'media volume' level.
Have a look at the MediaPlaybackService.java as used in the stock Music Player app and try to customize it as per your needs.

I havn't tried it myself. but looks like it should work. Kindly try it out.
m_audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
m_audioManager.setMode(AudioManager.MODE_IN_CALL);

Related

How can I use call sound not media sound with agora on the android web browser?

On Android Web Browser (Chrome or other browsers as well), the sound comes out to media sound, not the call sound. (in Demo too)
So, when the user controls the volume up/down buttons, it controls the call sound not the media sound. So, this misleads the users behaviours and it cause a lot of uncomfortable situations. And it's a bit difficult to control it on old android devices. Is there any way to solve this problem?
I tried with appRTC demo(https://appr.tc/). And the sound comes out to the call sound. And I can control the volume with the volume up/down buttons.
Please help me out. Thanks.
There isn't an API method to play audio as a call volume on the Agora Web SDK as of now. Media volume is the intended way of playing media on the browser. If you want to use the call volume you can check out the Android SDK instead.

Why it is not possible to play an audio file on a voice call in android

This question might seem to be a repetition of the questions such as following:
How to play an audio file on a voice call in android
Background Audio for a Call in Progress - Possible?
The answers of these questions suggests that it is not possible to play a pre-recorded audio on a voice call in android. I want to know why it is not possible? What is the limitation (hardware/software)? Is it really a limitation or done purposely? Can we alter the source code of android to make it possible?
I think this is a limitation, imposed for security reasons and restricted at the OS level.
Let's analyze the security threat, first of all. If you were able to play custom audio files to the callee, a whole world of cons opens up: you could trick customer supports, you could pretend to be someone else, you could give unauthorized purchase confirmations, and so on. For this reason, neither Android nor iOS allows this functionality.
On Android, you won't be able to do so in a programmatic way, simply because the current APIs won't allow you to do so. It is stated in the official documentation as well, as pointed out here. If you dig into the source code, you can probably enable this feature by accessing the microphone output during a phone call, but that would require running your custom version of Android. A good starting point would be the AudioTrack source, available here.
EDIT: a good example of an audio mod involves enabling the Nexus 5 earpiece as a second loudspeaker (requires root). Can be found here.
After a thorough research, what I have come to know is that there are more than one limitations/hurdles to make it possible. These limitations/hurdles are at three different levels.
First limitation is at API level, because there is no high-level API to play sound files in the conversation audio during a call as mentioned in Android official documentation.
Second limitation is at Radio Interface Layer (RIL). RIL passes on complete control of the call to Radio Daemon (rild) of the Linux library which then further passes the control to the vendor RIL. That means we cannot manipulate voice call in android source code.
Even if we are able to remove these two limitations, we may still not be able to play audio file to an ongoing voice call. Because there is a third limitation. Every vendor has their own library of RIL that communicates with Radio Daemon (rild). This requires that vendor RIL to be open source which is not actually. Hardware vendors do not usually make their device drivers code available.
Detail discussion on this topic is present at this link.
This is software related due to the prioritization of audio routing in Android.
Take a look into the CallManager where you can dig into the method setAudioMode(). After the audio mode was set to MODE_IN_COMMUNICATION the following code is called
audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
From this point on the telephony service has the highest priority and won't let any other audio play in parallel.
Note: You can play back the audio data only to the standard output device. Currently, that is the mobile device speaker or a Bluetooth headset. You cannot play sound files in the conversation audio during a call.
See official link
http://developer.android.com/guide/topics/media/mediaplayer.html
By implementing the AudioManager.OnAudioFocusChangeListener you can get the state of the audiomanager. so by this if any music is playing in the background you can get the AudioManager states(playing and pausing is completely in developer hands) similarly......
Some of the native music players in android device where handling this, they restrict the music when call is in TelephonyManager.EXTRA_STATE_OFFHOOK.so this scenario is also completely in developer hand (whether to handle or not) if he is not handling both will play parallel y

How can I auto-pause the audio player in my app when another app starts to play audio?

My app plays an audio file. I want my app to pause the audio playing if another apps starts to play audio. I don't want the two audio sounds mess up each other. My app will resume the audio playing after the other app finishes playing its audio. How can I make it? Thanks.
Depending on how your application is running ie. while app is running in foreground (users is looking at your screen) or if your running a "service" which is currently in the background and you wish music to continue playing (songza, slacker radio etc.) how you handle these things will be different. Android uses internal system states to determine which apps should be out-putting audio to the speaker. All this is handled by the audio manager requestAudioFocus() releaseAudioFocus() will be the system calls you will want to look at the most. For a more detailed explanation see android developer api where you this is explained and documented quite well http://developer.android.com/guide/topics/media/mediaplayer.html

How to bring audio from microphone to speaker on Android?

My problem is when I talk into the microphone, I want my sound to go to speaker of the phone which has Android OS. I think "MediaPlayer" class can't do it. Do you have any way?
Here you are not clear in which scenario you are going to do this but however it is possible to do using AudioManager, you can set your modes and audio services. For more details refer this link :
AudioManager

Is there any equivalent function of requestAudioFocus in Android API level 7?

My Android application needs to support Android platform 2.1.x (which is Android API level 7). I need to use requestAudioFocus() and abandonAudioFocus() methods to pause other applications (e.g. Music) to play when my application starts playing media and resume them after my application stops.
However, these two functions are only available at API Level 8 and above. What are the equivalent functions at API level 7? Or how to do this before API level 8?
Thanks to Christopher (http://stackoverflow.com/questions/1993471/android-can-i-mute-currently-playing-audio-applications), I am citating:
Audio handling on Android is going to be pretty horrible for a while. The APIs are pretty weird, poorly documented, and keep changing/deprecating/breaking between versions. Even the AudioManager code has FIXMEs in it.
Anyway, there are several stream types in Android (music, notifications, phone calls, etc.) and applications are meant to choose the appropriate one for playback. I imagine the majority of Android apps should use the music/media type (STREAM_TYPE_MUSIC). You set this on your MediaPlayer using the setAudioStreamType method.
The SDK does allow you to set a single stream type as solo — causing all other streams to be muted — but I don't believe you can identify the audio being played back by particular applications and somehow pause/unpause it. Music applications in general will use the PhoneStateListener to pause themselves when a call comes in.
So in your case, you could "borrow" the phone call stream for your MediaPlayer and use the method call AudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true) when playback begins, then un-solo the stream with false when playback or your Activity is done.
I can tell you that this works, but I can't remember offhand whether you need to also set the audio mode to MODE_IN_CALL when using the voice call stream (like this: AudioManager.setMode(AudioManager.MODE_IN_CALL)). If you find that is required, then you need to make sure you return the mode to MODE_NORMAL once playback completes, otherwise whenever you press the volume hard keys, it'll say "In-call volume"! However, if and when you do want to change back to MODE_NORMAL, you must check that a genuine phone call isn't happening at that time...
Maybe you could use another stream type rather than the voice call one, but I'm just speaking from experience working on an app that could use either the speakerphone or the earpiece for audio playback, which requires the use of the voice call stream.
Like I said, audio handling isn't particularly fun... ;)

Categories

Resources