diff --git a/src/BlueControl.uwp/App.xaml.cs b/src/BlueControl.uwp/App.xaml.cs
index 993a1e7..72a7f66 100644
--- a/src/BlueControl.uwp/App.xaml.cs
+++ b/src/BlueControl.uwp/App.xaml.cs
@@ -1,4 +1,6 @@
-using System;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Toolkit.Mvvm.DependencyInjection;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -39,6 +41,15 @@ namespace BlueControl.uwp
/// Details about the launch request and process.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
+
+ Ioc.Default.ConfigureServices(
+ new ServiceCollection()
+ .AddSingleton((input) => new Services.UiShellService(Window.Current.Dispatcher))
+ .AddSingleton()
+ .BuildServiceProvider());
+
+
+
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
diff --git a/src/BlueControl.uwp/BlueControl.uwp.csproj b/src/BlueControl.uwp/BlueControl.uwp.csproj
index 9113d68..0e597f4 100644
--- a/src/BlueControl.uwp/BlueControl.uwp.csproj
+++ b/src/BlueControl.uwp/BlueControl.uwp.csproj
@@ -123,6 +123,10 @@
MainPage.xaml
+
+
+
+
@@ -151,9 +155,21 @@
+
+ 6.0.0
+
6.2.12
+
+ 7.1.1
+
+
+ 2.0.1
+
+
+
+
14.0
diff --git a/src/BlueControl.uwp/MainPage.xaml b/src/BlueControl.uwp/MainPage.xaml
index 16726b1..f29d005 100644
--- a/src/BlueControl.uwp/MainPage.xaml
+++ b/src/BlueControl.uwp/MainPage.xaml
@@ -6,7 +6,20 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
- Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
+ xmlns:viewModels="using:BlueControl.uwp.ViewModels"
+ Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
+ xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
+ xmlns:core="using:Microsoft.Xaml.Interactions.Core"
+ >
+
+
+
+
+
+
+
+
+
diff --git a/src/BlueControl.uwp/MainPage.xaml.cs b/src/BlueControl.uwp/MainPage.xaml.cs
index 606f178..e71230d 100644
--- a/src/BlueControl.uwp/MainPage.xaml.cs
+++ b/src/BlueControl.uwp/MainPage.xaml.cs
@@ -28,13 +28,13 @@ namespace BlueControl.uwp
///
public sealed partial class MainPage : Page
{
- private ViewModels.MainPageViewModel vm = new ViewModels.MainPageViewModel();
+ //private ViewModels.MainPageViewModel vm = new ViewModels.MainPageViewModel();
public MainPage()
{
- this.vm.StaDispatcher = this.Dispatcher;
- this.DataContext = vm;
+ //this.vm.StaDispatcher = this.Dispatcher;
+ //this.DataContext = vm;
this.InitializeComponent();
- this.Loading += async (sender, args) => await vm.ReloadAsync();
+ //this.Loading += async (sender, args) => await vm.ReloadAsync();
}
}
diff --git a/src/BlueControl.uwp/Services/BluetoothService.cs b/src/BlueControl.uwp/Services/BluetoothService.cs
new file mode 100644
index 0000000..9fdb3f1
--- /dev/null
+++ b/src/BlueControl.uwp/Services/BluetoothService.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.Devices.Bluetooth;
+using Windows.Devices.Bluetooth.Advertisement;
+using Windows.Devices.Enumeration;
+
+namespace BlueControl.uwp.Services
+{
+ public class BluetoothService : IBluetoothService
+ {
+ private bool control = false;
+ public BluetoothService()
+ {
+
+
+
+ }
+
+ private BluetoothLEAdvertisementWatcher bleWatcher = null;
+ public async Task IsConnectedAsync(string deviceName)
+ {
+ return (from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromConnectionStatus(BluetoothConnectionStatus.Connected)) where x.Name == deviceName select x).Any();
+ }
+
+ public async Task IsPairedAsync(string deviceName)
+ {
+ return (from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true)) where x.Name == deviceName select x).Any();
+ }
+
+ public async Task UnpairAsync(string deviceName)
+ {
+ var device = (from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true)) where x.Name == deviceName select x).FirstOrDefault();
+ if (device != null)
+ await device.Pairing.UnpairAsync();
+ }
+
+ private Action pinCreatedCallBack = null;
+ private void Custom_PairingRequested(DeviceInformationCustomPairing sender, DevicePairingRequestedEventArgs args)
+ {
+
+ if (this.pinCreatedCallBack != null) pinCreatedCallBack(args.Pin);
+ args.Accept(args.Pin);
+ }
+
+ public async Task StartAutoPairingAsync(string deviceName, Action onFoundTryingToPair, Action onPinCreated, Action onSuccess, Action onError)
+ {
+ pinCreatedCallBack = onPinCreated;
+
+ if (this.bleWatcher == null)
+ {
+ this.bleWatcher = new BluetoothLEAdvertisementWatcher();
+ this.bleWatcher.Received += async (sender, args) =>
+ {
+ try
+ {
+ if (!args.IsConnectable || control == true) return;
+ control = true;
+ var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
+ if (dev.Name == deviceName && dev.DeviceInformation.Pairing.CanPair)
+ {
+ if (onFoundTryingToPair != null) onFoundTryingToPair();
+
+ System.Threading.Thread.Sleep(3000);
+ dev.DeviceInformation.Pairing.Custom.PairingRequested += Custom_PairingRequested;
+ var t = await dev.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.DisplayPin, DevicePairingProtectionLevel.Encryption);
+ if (t.Status == DevicePairingResultStatus.Paired)
+ {
+ this.bleWatcher.Stop();
+ if (onSuccess != null) onSuccess();
+ }
+ else
+ if (onError != null) onError();
+ }
+ }
+ catch { }
+ control = false;
+
+ };
+
+ }
+ this.bleWatcher.Start();
+ }
+
+
+ }
+}
diff --git a/src/BlueControl.uwp/Services/IBluetoothService.cs b/src/BlueControl.uwp/Services/IBluetoothService.cs
new file mode 100644
index 0000000..2c64f61
--- /dev/null
+++ b/src/BlueControl.uwp/Services/IBluetoothService.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BlueControl.uwp.Services
+{
+ public interface IBluetoothService
+ {
+ Task IsConnectedAsync(string deviceName);
+ Task IsPairedAsync(string deviceName);
+ Task UnpairAsync(string deviceName);
+ Task StartAutoPairingAsync(string deviceName, Action onFoundTryingToPair, Action onPinCreated, Action onSuccess, Action onError);
+
+
+ }
+}
diff --git a/src/BlueControl.uwp/Services/IShellService.cs b/src/BlueControl.uwp/Services/IShellService.cs
new file mode 100644
index 0000000..f9c7193
--- /dev/null
+++ b/src/BlueControl.uwp/Services/IShellService.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BlueControl.uwp.Services
+{
+ public interface IShellService
+ {
+ Task UiStaRunAsync(Action action);
+ void CloseApplication();
+ }
+}
diff --git a/src/BlueControl.uwp/Services/UiShellService.cs b/src/BlueControl.uwp/Services/UiShellService.cs
new file mode 100644
index 0000000..161f7b4
--- /dev/null
+++ b/src/BlueControl.uwp/Services/UiShellService.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BlueControl.uwp.Services
+{
+ public class UiShellService : IShellService
+ {
+ public async Task UiStaRunAsync(Action action)
+ {
+ if (StaDispatcher != null)
+ await StaDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => action());
+ }
+
+ public Windows.UI.Core.CoreDispatcher StaDispatcher { get; set; }
+
+ public UiShellService(Windows.UI.Core.CoreDispatcher dispacher)
+ {
+ this.StaDispatcher = dispacher;
+ }
+
+ public void CloseApplication()
+ {
+ App.Current.Exit();
+ }
+
+ }
+}
diff --git a/src/BlueControl.uwp/ViewModels/MainPageViewModel.cs b/src/BlueControl.uwp/ViewModels/MainPageViewModel.cs
index d696252..072f77a 100644
--- a/src/BlueControl.uwp/ViewModels/MainPageViewModel.cs
+++ b/src/BlueControl.uwp/ViewModels/MainPageViewModel.cs
@@ -1,9 +1,12 @@
-using System;
+using Microsoft.Toolkit.Mvvm.DependencyInjection;
+using Microsoft.Toolkit.Mvvm.Input;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows.Input;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Enumeration;
@@ -14,22 +17,18 @@ namespace BlueControl.uwp.ViewModels
public class MainPageViewModel : INotifyPropertyChanged
{
private const string SURFACE_KEYBOARD_NAME = "Surface Keyboard";
- private readonly BluetoothLEAdvertisementWatcher bleWatcher = new BluetoothLEAdvertisementWatcher();
- private bool control = false;
- public Windows.UI.Core.CoreDispatcher StaDispatcher { get; set; }
- public async Task StaExecuteAsync(Action action)
- {
- if (StaDispatcher != null)
- await StaDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => action());
- }
+
+
+
+
private void CloseApplication(TimeSpan delta)
{
var dispatcherTimer = new DispatcherTimer();
- dispatcherTimer.Tick += (o, e) => App.Current.Exit();
+ dispatcherTimer.Tick += (o, e) => ShellService.CloseApplication();
dispatcherTimer.Interval = delta;
dispatcherTimer.Start();
}
@@ -40,48 +39,21 @@ namespace BlueControl.uwp.ViewModels
}
- private void Custom_PairingRequested(DeviceInformationCustomPairing sender, DevicePairingRequestedEventArgs args)
- {
- StaExecuteAsync(() => this.Text = "Pin: " + Environment.NewLine + args.Pin);
- args.Accept(args.Pin);
- }
+ private readonly Services.IShellService ShellService = Windows.ApplicationModel.DesignMode.DesignModeEnabled
+ ? null : Ioc.Default.GetRequiredService();
+
+ private readonly Services.IBluetoothService BluetoothService = Windows.ApplicationModel.DesignMode.DesignModeEnabled
+ ? null : Ioc.Default.GetRequiredService();
+
+
public MainPageViewModel()
{
- this.bleWatcher.Received += async (sender, args) =>
- {
- try
- {
- if (!args.IsConnectable || control == true) return;
- control = true;
- var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
- if (dev.Name == SURFACE_KEYBOARD_NAME && dev.DeviceInformation.Pairing.CanPair)
- {
- await StaExecuteAsync(() => this.Text = "trying to pair... ");
+ this.ReloadCommand = new RelayCommand(async () => await ReloadAsync());
- System.Threading.Thread.Sleep(3000);
- dev.DeviceInformation.Pairing.Custom.PairingRequested += Custom_PairingRequested;
- var t = await dev.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.DisplayPin, DevicePairingProtectionLevel.Encryption);
- if (t.Status == DevicePairingResultStatus.Paired)
- {
- this.bleWatcher.Stop();
- await StaExecuteAsync(() =>
- {
- this.Text = $"Paired and connected {Environment.NewLine} auto closing in 2 seconds ";
- CloseApplication();
- }
- );
- }
- else
- await StaExecuteAsync(() => this.Text = t.Status.ToString());
- }
- }
- catch { }
- control = false;
-
- };
+
}
@@ -110,22 +82,32 @@ namespace BlueControl.uwp.ViewModels
public event PropertyChangedEventHandler PropertyChanged;
+ public ICommand ReloadCommand { get; private set; }
+
public async Task ReloadAsync()
{
this.Text = "Loading...";
- IsConnected =
- (from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromConnectionStatus(BluetoothConnectionStatus.Connected)) where x.Name == SURFACE_KEYBOARD_NAME select x).Any();
+ IsConnected = await BluetoothService.IsConnectedAsync(SURFACE_KEYBOARD_NAME);
if (!IsConnected)
{
- var pairedDevice =
- (from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true)) where x.Name == SURFACE_KEYBOARD_NAME select x).FirstOrDefault();
- if (pairedDevice != null)
- await pairedDevice.Pairing.UnpairAsync();
+ if (await BluetoothService.IsPairedAsync(SURFACE_KEYBOARD_NAME))
+ await BluetoothService.UnpairAsync(SURFACE_KEYBOARD_NAME);
this.Text = $"....searching keyboard. {Environment.NewLine} Please confirm is in pairing mode";
- this.bleWatcher.Start();
+ await this.BluetoothService.StartAutoPairingAsync(
+ SURFACE_KEYBOARD_NAME,
+ () => this.ShellService.UiStaRunAsync(() => this.Text = "trying to pair... ")
+ , (pin) => this.ShellService.UiStaRunAsync(() => this.Text = $"pin:{Environment.NewLine + pin}")
+ , () =>
+ ShellService.UiStaRunAsync(() =>
+ {
+ this.Text = $"Paired and connected {Environment.NewLine} auto closing in 2 seconds ";
+ CloseApplication();
+ })
+ , () => ShellService.UiStaRunAsync(() => this.Text = "error trying again")
+ );
}
else
{