So I am trying to use some code found here on Stack Overflow in order to route audio from the Headset to the Speakers.
What I am currently doing is:
AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.STREAM_MUSIC);
am.setSpeakerphoneOn(true);
sleep(15000);
What happens is that the audio is routed during the "sleep", however it gets back to the headset after the 15 seconds.
If I perform this without the sleep, the sound will go to the speaker and back to the headset very quickly.
After this call, my program dies. I would like that this would persist in the system, as the app Headset Toggle does
I could not discover why my method wasn't working, but I found a workaround for it.
What I am doing at the moment is:
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
Thanks to Michael from this post.
Related
For some reason and specifically on an Acer Iconia tablet if setPlaybackParams() is called before starting the media player and after the MediaPlayer is prepared, nothing happens: start() 'succeeds' and no audio is heard.
Everything works in the emulator and other devices I have as well as a few thousand devices using the app.
How can I detect this failure on this and other devices that don't work well with setPlaybackParams() if no exceptions are thrown and no errors are generated? The only solution I can think of is having a playback timeout mechanism. Are there any others?
This is how I solved this problem for my own application:
My app has a playback progress broadcaster that starts when onPrepared(), it broadcasts the mediaplayer progress to any UI elements interested in it. I added gear in it to detect the condition where onPrepared() calls MediaPlayer->start() but doesn't exhibit any playback progress (The mediaPlayer stalls).
The progress broadcaster runs once a second and has this code in it:
int stall_cntr = 3;
// WORKAROUND FOR ACER ICONIA TABLETS
// Gear to detect if stall has occured.
if (last_position != position) {
last_position = position;
} else {
// last position is the same it previously was which shouldn't happen if
// mediaplayer isPlaying
if (stall_cntr == 0) {
// set setPlaybackParam_unsupported configuration value.
SharedPreferences settings = mService.getApplicationContext().getSharedPreferences(Settings.metapod_settings, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("setplaybackparams_not_supported", true);
editor.apply();
} else {
stall_cntr--;
}
}
The code will detect a media player stall (where onPrepared calls start() but progress isn't realized) in 3 seconds. If a stall is detected then the features that require setPlaybackParam() API is disabled thus avoiding the issue instead of fixing it...
I'm playing an audio clip using OpenSL ES. In my code I have
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
to force audio through the speaker while the headset is plugged in. It works fine, but I can't control the volume. Pressing the volume buttons while the clip is playing makes the volume seekbar appear and move, but the volume doesn't change.
Calling setVolumeControlStream(AudioManager.STREAM_VOICE_CALL) or setVolumeControlStream(AudioManager.STREAM_MUSIC) before playing doesn't seem to help.
Changing any of the volumes outside of my app (e.g. in the Android settings) doesn't affect the playing volume. Volume control works well on both headset and speaker when no routing is applied.
I've also tried routing the audio to the speaker using this code I found in another answer
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
but it doesn't work on my Android 4.3 Nexus 4. I need the most compatible way to to that anyway.
Any ideas?
Thanks.
Here is a couple ideas:
MODE_IN_CALL sets all sorts of priority/policy on STREAM_VOICE_CALL. During this time, other STREAM may loose volume control focus. See if your audio clip is played over STREAM_VOICE_CALL.
MODE_IN_COMMUNICATION (for VoIP) may be a better fit for you. MODE_IN_CALL is for cellular call and can degrade your audio quality.
You may want to try grab audio focus and see if that helps. http://developer.android.com/training/managing-audio/audio-focus.html
I connected usb handsfree to my android device. I need to switch sound input between handfree and built-in microphone. In some devices (like mk802 hdmi-tv-console) threre is system menu where sound input and output could be changed.
I searching a way to change input and ouput from console or from code.
I'm not aware of any official way of doing what you want. The rationale being something like: if you didn't want to use the handsfree you wouldn't have plugged it in in the first place.
There are a few things you could try, but they're not guaranteed to work across all devices and Android versions.For playback you could try this to get the audio routed to the loudspeaker instead of the USB accessory:
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
And for recording you could try using the VOICE_CALL or CAMCORDER AudioSource instead of MIC or DEFAULT.
I am developing an app. I need to play the music when i am in a call. But i am facing with the problem that whenever i try to play the music in a call it is not that much loud as it is when there is no call.
Is there any way to control the background music when in a call. My music volume becomes softer when i am in a call but it becomes louder as soon as i end the call.
final AudioManager mAudioManager = (AudioManager) ctx
.getSystemService(AUDIO_SERVICE);
final int originalVolume = mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
mAudioManager
.setStreamVolume(
AudioManager.STREAM_MUSIC,
mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
0);
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mAudioManager.setMode(AudioManager.MODE_NORMAL);
Class audioSystemClass = Class
.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod(
"setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go
// back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
this is my code.
I see that you're trying to use the "force music streams to the loudspeaker"-method I posted in an answer to another question.
The problem is that during voice calls, music streams will follow the voice call's routing and ignore the FOR_MEDIA force flag. So what you perceive as lower volume is most likely the result of the music being played from the earpiece instead of from the loudspeaker.
To my knowledge, there's no way of routing the music to the loudspeaker during an ongoing call without also routing the voice call to the loudspeaker (i.e. using setSpeakerPhoneOn).
Depending on how your phone manufacturer/carrier implemented Android AudioPolicyService, some implementation lowers STREAM_MUSIC volume when MODE_IN_CALL/MODE_IN_COMMUNICATION is in session.
I have not tried this, but a likely workable solution is to use STREAM_VOICE_CALL instead of STREAM_MUSIC. Your audio stream should then play along with the in call audio stream just fine.
I'd like to use the speaker for audio output while simultaneously using the headphone jack for a different audio output/input. Is this possible?
It's possible to do on some devices (I've verified that it works on a Sony XPeria P), but I don't think you can count on it to work on all devices.
What you'd do is force MUSIC streams to route to the loudspeaker:
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
Then you use the MUSIC stream for anything you want routed to the loudspeaker, and the VOICE_CALL stream for anything you want routed to the headset/headphones.
See my answer for Playing sound over speakers while playing music through headphones