I want to get current playing audio device (like phone, wired headphones or bluetooth device). Do you know how to get?
My code:
val manager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
return if (manager.isBluetoothScoOn) "Bluetooth"
else if (!manager.isBluetoothScoOn && !manager.isSpeakerphoneOn) "Wired"
else "Phone"
Related
I need to have some custom behavior in my app when the audio playback is done on the device speaker (not a wired headphone and not a BlueTooth receiver).
To do so I'm doing the following
AudioManager audioManager = (AudioManager) service.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
isSpeakerPhoneOn = audioManager.isSpeakerphoneOn();
But isSpeakerPhoneOn is always false.
By the way, I'm calling the code after playback is started.
Any idea what I'm doing wrong?
I suggest you to try this
AudioManager manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
if(manager.isMusicActive())
{
// do something - or don't
}
I am creating Media Player, but it should never play on Speaker. If head phone jack or bluetooth is not available, still Audio should not be played over speaker.
I used below Android API but it still plays over speaker:
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
am.setSpeakerphoneOn(false);
You can check the whether Bluetooth and headphone connected or not by using Broadcast receiver using this link http://blog.urvatechlabs.com/detect-programatically-if-headphone-or-bluetooth-headsets-attached-with-android-phone/ . If it is not connected/removed pause/stop the Android Media Player.
From AudioManager official documentation
audioManager.setSpeakerphoneOn(boolean)
Sets the speakerphone on or off.
It means if you set the false it will disable the speaker sound i.e playing out from the speaker and if you set true it will play from the speaker.
In your case, you don't want to play your music from the outer speaker but still your using the am.setSpeakerphoneOn(true); which is actually enables the outer speaker.
So set am.setSpeakerphoneOn(false); so that it won't play the music from outer speaker
You can also set the Mode ( Call / Voice Communication / Music etc) for your AudioManager
audioManager.setMode(AudioManager.STREAM_MUSIC);
Note:: For changing the audio manager settings you need to set Permission: MODIFY_AUDIO_SETTINGS in manifest
add this line in manifest
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
In additional, this is the code to check which type of audio conncection
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
PackageManager packageManager = getPackageManager();
if (audioManager.isBluetoothA2dpOn()) {
// Adjust output for Bluetooth.
Log.d("debug","BluetoothA2dpOn");
} else if (audioManager.isBluetoothScoOn()) {
// Adjust output for Bluetooth of sco.
Log.d("debug","BluetoothScoOn");
} else if (audioManager.isWiredHeadsetOn()) {
// Adjust output for headsets
Log.d("debug","WiredHeadsetOn");
} else if (audioManager.isSpeakerphoneOn()) {
// Adjust output for Speakerphone.
Log.d("debug","SpeakerphoneOn");
} else if (packageManager.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
// Has internal speaker or other form of audio output.
Log.d("debug","Internal Speaker On");
} else {
// No device for audio output.
Log.d("debug","No Audio Device");
}
So I wrote this piece for an Android App. The idea is simple:
Detect whether sound is playing and if yes open the BluethoothSCO Channel so the audio gets played there.
I want to use it to "route" the navigation direction infos to my car speaker. It works nearly like expected.
There is a 'huge' delay of around 1 second between the audio recognition and the bluethoothsco connection being ready. This results in a loss of nearly half the navigation information.
My Idea was to add a delay or pause the playback for a second.
NOW: Sound is detected -> BluethootSCO opening (sound keeps playing here) -> sound over car speaker
IDEA: Sound is detected -> pause/delay for 1 sec ->BluethootSCO opening -> resume playback -> sound over car speaker
I thought about recording it and playing it afterwards but that would be to late for some informations like "turn left NOW".
A short delay would be ok, but I have no idea on to implement this :(
Since the app is only for myself using root would be ok.
Maybe there is an possibility direct at the AudioFlinger?
public void checkSound() {
AudioManager localAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
Visualizer localVisualizer = new Visualizer(0);
localVisualizer.setEnabled(true);
Visualizer.MeasurementPeakRms localPeak = new Visualizer.MeasurementPeakRms();
boolean wasPlayingBefore=false;
while (keeprunning) //Loop to detect changes on the Media Audio Stream
{
localVisualizer.getMeasurementPeakRms(localPeak);
if(localPeak.mPeak > -8500 && !wasPlayingBefore)
{
//There is some audio output
wasPlayingBefore=true;
localAudioManager.setBluetoothScoOn(true);
localAudioManager.startBluetoothSco();
localAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
android.os.SystemClock.sleep(5000); //Route to BT Headset will exist min. 5 seconds ...
}
if(localPeak.mPeak <= -8500 && wasPlayingBefore)
{
//output (temporary) gone
android.os.SystemClock.sleep(2000);//... plus this 2 seconds
//check again
localVisualizer.getMeasurementPeakRms(localPeak);
}
if(localPeak.mPeak <= -8500 && wasPlayingBefore)
{
//Audio didn't get back in last 2 seconds...
wasPlayingBefore=false;
localAudioManager.setBluetoothScoOn(false);
localAudioManager.stopBluetoothSco();
localAudioManager.setMode(AudioManager.MODE_NORMAL);
}
android.os.SystemClock.sleep(100); //Slow down the loop
Log.d("Peak", String.valueOf(localPeak.mPeak));//Debug info - Audio peak -9600 = Silent, 0 = MAX Output
}
localVisualizer.release();
}
How to check if a device running Android has a speaker on it or not? Meaning is it able to play audio?
Are there any Configuration qualifiers for it? and what about programmatically
EDIT: just bought an Android Wear watch and it does NOT have a speaker so not sure how I would check this
Since API level 21 (most Android Wear based on this level), Android provide a feature, PackageManager.FEATURE_AUDIO_OUTPUT, witch can be used to detect whether there is a way to output the audio.
I tested this feature on my MOTO 360 (no speaker), it don't has this feature, and Ticwatch (with speaker) do have this feature.
But when I connected a Bluetooth headset to the MOTO 360, it still don't have this feature, this confused me.
So I use AudioManager.isBluetoothA2dpOn() for further check.
The detection code can be like this:
public boolean hasAudioOutput() {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
PackageManager packageManager = getPackageManager();
if (audioManager.isBluetoothA2dpOn()) {
// Adjust output for Bluetooth.
return true;
} else if (audioManager.isBluetoothScoOn()) {
// Adjust output for Bluetooth of sco.
return true;
} else if (audioManager.isWiredHeadsetOn()) {
// Adjust output for headsets
return true;
} else if (audioManager.isSpeakerphoneOn()) {
// Adjust output for Speakerphone.
return true;
} else if (packageManager.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
// Has internal speaker or other form of audio output.
return true;
} else {
// No device for audio output.
return false;
}
}
Android API doesn't have any such qualifiers neither there is any library method.
But just a raw idea, try playing some audio and simultaneously record through the mic.
Check if they are same.
This is not a fool proof way, but just a thought!
Probably most android phones have a speaker i guess :P /.. But if you are asking if you can check whether its connected to a speaker or headphones or something like that..then you can use
if (isBluetoothA2dpOn()) {
// Adjust output for Bluetooth.
} else if (isSpeakerphoneOn()) {
// Adjust output for Speakerphone.
} else if (isWiredHeadsetOn()) {
// Adjust output for headsets
} else {
// If audio plays and noone can hear it, is it still playing?
}
SOURCE: http://developer.android.com/training/managing-audio/audio-output.html#CheckHardware
I'm doing some test with Intent.ACTION_HEADSET_PLUG.
Giving the fact that the following code should be the one who give the responses (From com.android.server.HeadsetObserver class 2.2.1 r1):
private final void sendIntent(int headset, int headsetState, int prevHeadsetState, String headsetName) {
if ((headsetState & headset) != (prevHeadsetState & headset)) {
// Pack up the values and broadcast them to everyone
Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
int state = 0;
int microphone = 0;
if ((headset & HEADSETS_WITH_MIC) != 0) {
microphone = 1;
}
if ((headsetState & headset) != 0) {
state = 1;
}
intent.putExtra("state", state);
intent.putExtra("name", headsetName);
intent.putExtra("microphone", microphone);
if (LOG) Slog.v(TAG, "Intent.ACTION_HEADSET_PLUG: state: "+state+" name: "+headsetName+" mic: "+microphone);
// TODO: Should we require a permission?
ActivityManagerNative.broadcastStickyIntent(intent, null);
}
}
And in the documentation they say: state - 0 for unplugged, 1 for plugged.
I strangely get two different state by plugging two different headsets:
0 = unplugged
1 = Headset with microphone
2 = Headset without microphone
The question is: where the State 2 (two) come from? Can someone enlighten me?
Thanks
I am using that extra state myself in one of my applications. One of your headsets has a mic the other doesn't. Also make sure you a plugging it in all the way, but don't break anything :)
0 - unplugged as in no headset attached to the device
1 - headset with microphone as in wired headset that had a mic so you can talk and the device uses it as a input as you talk
2 - a headset with no microphone as in your regular old stereo headset that you would normally hook up to your stereo system to listen to music with
This is extremely good info to verify that what was just connected is a wired headset that you expect to be able to talk in to and be heard correctly.