172 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Diagnostics;
 | |
| using System.Threading.Tasks;
 | |
| using System.Timers;
 | |
| using Windows.Devices.Bluetooth;
 | |
| using Windows.Devices.Radios;
 | |
| 
 | |
| namespace MeetingClock
 | |
| {
 | |
|     public class BluetoothManager
 | |
|     {
 | |
|         public enum BluetoothState
 | |
|         {
 | |
|             NotInitialized,
 | |
|             Exception,
 | |
|             NoBluetoothAdapter,
 | |
|             NoBluetoothRadio,
 | |
|             Disabled,
 | |
|             Off,
 | |
|             On,
 | |
|             Unknown
 | |
|         }
 | |
| 
 | |
|         public delegate void BluetoothStateChangeHandler(BluetoothManager manager, BluetoothState oldState, BluetoothState newState);
 | |
|         public event BluetoothStateChangeHandler StateChanged;
 | |
| 
 | |
|         public BluetoothState State { get; private set; } = BluetoothState.NotInitialized;
 | |
| 
 | |
|         private BluetoothAdapter adapter;
 | |
|         private Radio radio;
 | |
|         private Timer updateTimer;
 | |
| 
 | |
|         public BluetoothManager()
 | |
|         {
 | |
|             this.updateTimer = new Timer(100);
 | |
|             this.updateTimer.Elapsed += UpdateTimer_Elapsed;
 | |
|         }
 | |
| 
 | |
|         public async Task Initialize()
 | |
|         {
 | |
|             await this.InitializePrivate(true);
 | |
|         }
 | |
| 
 | |
|         private async Task InitializePrivate(bool withLog)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 this.adapter = await BluetoothAdapter.GetDefaultAsync();
 | |
|                 if (this.adapter == null)
 | |
|                 {
 | |
|                     if (withLog)
 | |
|                     {
 | |
|                         Debug.WriteLine("No BluetoothAdapter found");
 | |
|                     }
 | |
|                     this.State = BluetoothState.NoBluetoothAdapter;
 | |
|                     this.StateChanged(this, BluetoothState.NotInitialized, BluetoothState.NoBluetoothAdapter);
 | |
|                     this.updateTimer.Start();
 | |
|                     return;
 | |
|                 }
 | |
|                 if (withLog)
 | |
|                 {
 | |
|                     Debug.WriteLine(String.Format("Found BluetoothAdapter device id: {0}, address: {1}", this.adapter.DeviceId, this.adapter.BluetoothAddress));
 | |
|                 }
 | |
| 
 | |
|                 this.radio = await this.adapter.GetRadioAsync();
 | |
|                 if (this.radio == null)
 | |
|                 {
 | |
|                     if (withLog)
 | |
|                     {
 | |
|                         Debug.WriteLine("No Radio found");
 | |
|                     }
 | |
|                     this.State = BluetoothState.NoBluetoothRadio;
 | |
|                     this.StateChanged(this, BluetoothState.NotInitialized, BluetoothState.NoBluetoothRadio);
 | |
|                     this.updateTimer.Start();
 | |
|                     return;
 | |
|                 }
 | |
|                 if (withLog)
 | |
|                 {
 | |
|                     Debug.WriteLine(String.Format("Found Bluetooth Radio device: {0}", this.radio.Name));
 | |
|                 }
 | |
| 
 | |
|                 this.radio.StateChanged += Radio_StateChanged;
 | |
|                 this.UpdateState();
 | |
| 
 | |
|                 if (withLog)
 | |
|                 {
 | |
|                     Debug.WriteLine(String.Format("Bluetooth State: {0}", this.State));
 | |
|                 }
 | |
| 
 | |
|                 this.updateTimer.Start();
 | |
|             }
 | |
|             catch (Exception exception)
 | |
|             {
 | |
| 
 | |
|                 if (withLog)
 | |
|                 {
 | |
|                     Debug.WriteLine(String.Format("Exception while discovering bluetooth adapter, radio, and state: {0}", exception.Message));
 | |
|                 }
 | |
|                 this.State = BluetoothState.Exception;
 | |
|                 this.StateChanged(this, BluetoothState.NotInitialized, BluetoothState.Exception);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void UpdateState() {
 | |
|             RadioState state = this.radio.State;
 | |
|             BluetoothState oldState = this.State;
 | |
|             BluetoothState btState;
 | |
|             switch (state)
 | |
|             {
 | |
|                 case RadioState.Disabled:
 | |
|                     btState = BluetoothState.Disabled;
 | |
|                     break;
 | |
|                 case RadioState.Off:
 | |
|                     btState = BluetoothState.Off;
 | |
|                     break;
 | |
|                 case RadioState.On:
 | |
|                     btState = BluetoothState.On;
 | |
|                     break;
 | |
|                 default:
 | |
|                     btState = BluetoothState.Unknown;
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             if (btState != this.State)
 | |
|             {
 | |
|                 Debug.WriteLine(String.Format("New Bluetooth state detected. Old state {0}, new state {1}", this.State, btState));
 | |
|                 this.State = btState;
 | |
|                 if (this.StateChanged != null)
 | |
|                 {
 | |
|                     this.StateChanged(this, oldState, btState);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void Radio_StateChanged(Radio sender, object args)
 | |
|         {
 | |
|             this.UpdateState();
 | |
|         }
 | |
| 
 | |
|         private async void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e)
 | |
|         {
 | |
|             switch (this.State)
 | |
|             {
 | |
|                 case BluetoothState.Exception:
 | |
|                     this.updateTimer.Stop();
 | |
|                     break;
 | |
|                 case BluetoothState.NotInitialized:
 | |
|                 case BluetoothState.NoBluetoothAdapter:
 | |
|                 case BluetoothState.NoBluetoothRadio:
 | |
|                     await this.InitializePrivate(false);
 | |
|                     break;
 | |
|                 default:
 | |
|                     this.UpdateState();
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public async Task<RadioAccessStatus> Enable()
 | |
|         {
 | |
|             if (this.radio != null) {
 | |
|                 return await this.radio.SetStateAsync(RadioState.On);
 | |
|             }
 | |
|             return RadioAccessStatus.Unspecified;
 | |
|         }
 | |
| 
 | |
|         public void Stop()
 | |
|         {
 | |
|             this.updateTimer.Stop();
 | |
|         }
 | |
|     }
 | |
| }
 | 
