Some time ago, a friend who is working on a big WP8 project, asked me for a method to detect when the headphone jack is plugged or unplugged from the device, given that apparently there were no API to do this.
I also do not know the answer and not even my internet searches give any success.
My first idea was to use the FM radio API to measure signal strength, as the headset is used as an antenna for the radio synth, I thought that the presence of plug in device would increase the level of the received signal.
I did some experiment with FMRadio.Instance.SignalStrength by measuring the strength change plugging and unplugging an headset.
But this simply cannot work with first generation WP8 (til the GDR1 update) did not have access to FM radio API and simple an exception is generated when the radio is istantiated.
I test the method with WP7 device, but the variations in the signal strength were not so relevant to determine the presence or absence of the headset.
I have conducted similar tests on device WP8 with GDR2, but the results were the same.
When I understand that this approach can’t solve the problem, I start a new search in WP8 API and found that among the VOIP API was an interesting AudioRoutingManager class.
The use of this API is to route the audio to VOIP communications endpoints other than the phone's speaker.
However, the class implements a AudioEndPointChanged event that lets you know the current audio endpoint device or if there was a change from the previous state, the values are exposed by an enumerator AudioRoutingEndpoint with the following members:
|Default||The default audio endpoint, that is, the speakerphone.|
|Bluetooth||A Bluetooth device.|
|WiredHeadset||A wired headset.|
|WiredHeadsetSpeakerOnly||A wired headset for output only; the input is received from the default microphone.|
|BluetoothWithNoiseAndEchoCancellation||A Bluetooth device with noise and echo cancellation.|
Voila! Registering to the event we’ll be "notified" when the status changes accordingly and know if the jack is inserted or not.
With this method we can detect many more information, as seen in the previous table, but we will manage only the one we need in each case.
Let's see then some code from the example that is linked at the end of the post.
In order to make anything work we have to add a new capabilities in the WMAppManifest, and specifically the ID_CAP_VOIP one.
First of all we register to the event with our handler:
1: AudioRoutingManager.GetDefault().AudioEndpointChanged += MainPage_AudioEndpointChanged;
Then how to handle each case in out method:
1: public void MainPage_AudioEndpointChanged(AudioRoutingManager sender, object args)
3: var AudioEndPoint = sender.GetAudioEndpoint();
4: switch (AudioEndPoint)
6: case AudioRoutingEndpoint.Default:
8: txtActual = "Default";
11: case AudioRoutingEndpoint.Earpiece:
13: txtActual = "Earpiece";
16: case AudioRoutingEndpoint.Speakerphone:
18: txtActual = "Speakerphone";
21: case AudioRoutingEndpoint.Bluetooth:
23: txtActual = "Bluetooth";
26: case AudioRoutingEndpoint.WiredHeadset:
28: txtActual = "WiredHeadset";
31: case AudioRoutingEndpoint.WiredHeadsetSpeakerOnly:
33: txtActual = "WiredHeadsetSpeakerOnly";
36: case AudioRoutingEndpoint.BluetoothWithNoiseAndEchoCancellation:
38: txtActual = "BluetoothWithNoiseAndEchoCancellation";
42: throw new ArgumentOutOfRangeException();
In this code I managed all the possible case in order to verify each combination of wired or wireless connection.
To test it after launching the App, insert an earphone in the device and you’ll see a corresponding message on screen.
ATTENTION: I have tested GDR1 and GDR2 device, the app work on all device, but on GDR1 simply it doesn’t work and don’t show the changing values displayed.
I have no idea why it doesn't work, since VOIP APIs are implemented and working since the release of WP8.
Obviously the above applies only to device WP8.
You can find the source code of the sample app at this link .