什么是WINDOWS UWP
UWP即Windows 10 中的Universal Windows Platform简称。即Windows通用应用平台,在Win 10 Mobile/Surface(Windows平板电脑)/PC/Xbox/HoloLens等平台上运行,uwp不同于传统pc上的exe应用也跟只适用于手机端的app有本质区别。它并不是为某一个终端而设计,而是可以在所有windows10设备上运行。
微软在MWC 2015上首次展示了Win10统一平台战略的“代表作”:Win10通用应用(Windows10 Universal App)平台。在Win10中,所有设备将会运行在一个统一的Windows10系统核心之上。这样的设计使得一款应用可以在所有Win10设备上运行,今后Win10手机、平板电脑、笔记本电脑、PC、Xbox,甚至是3D全息眼镜HoloLens、巨屏触控Surface Hub和物联网设备例如Raspberry Pi 2等都不再有界限。新的通用平台允许新类型的Windows10通用应用真正实现一次编写、一套业务逻辑和统一的用户界面。应用在统一的Win10商店中将只会有一个安装包,而它将适用于所有Win10设备。[1]在 Windows 10 Insider Preview 中的 Universal Windows Platform (UWP)借助 Windows 10 UWP 将在 Windows 应用中更上一层楼。UWP 会根据不同的设备类型使用相应的自适应 UI 控件,并使用运行 Windows 10 Insider Preview 的所有设备上必须具有的通用 API 集。简单的说,uwp就是通用应用的意思可以在电脑端,手机端,或其他设备通用。不用分别为不同的平台设计不同的软件。即一个软件就可以通吃。这估计现在是win10系统的一个软件发展趋势了。不管是开发者,还是使用者,都省事。
什么是蓝牙BLE
蓝牙低能耗(BLE)技术是低成本、短距离、可互操作的鲁棒性无线技术,工作在免许可的2.4GHz ISM射频频段。它从一开始就设计为超低功耗(ULP)无线技术。它利用许多智能手段最大限度地降低功耗。蓝牙低能耗技术采用可变连接时间间隔,这个间隔根据具体应用可以设置为几毫秒到几秒不等。另外,因为BLE技术采用非常快速的连接方式,因此平时可以处于“非连接”状态(节省能源),此时链路两端相互间只是知晓对方,只有在必要时才开启链路,然后在尽可能短的时间内关闭链路。
BLE技术的工作模式非常适合用于从微型无线传感器(每半秒交换一次数据)或使用完全异步通信的遥控器等其它外设传送数据。这些设备发送的数据量非常少(通常几个字节),而且发送次数也很少(例如每秒几次到每分钟一次,甚至更少)。
用Visual Studio 2015 开发一个BLE扫描程序
打开VISUAL STUDIO, 新建一个空白应用(通用WINDOWS)
将工程名称命名为 BleScanner
UWP平台处理蓝牙BLE的命名空间主要有下列几个
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Devices.Bluetooth;
我们将会用到的类是 BluetoothLEAdvertisementWatcher, 这个类负责扫描所有的BLE设备。
代码如下
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Devices.Bluetooth;
using System.Diagnostics;
using System.Collections.ObjectModel;
using Windows.UI.Xaml.Shapes;
using Windows.UI;
//“空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 上有介绍
namespace BleScanner
{
/// <summary>
/// 可用于自身或导航至 Frame 内部的空白页。
/// </summary>
public sealed partial class MainPage : Page
{
BluetoothLEAdvertisementWatcher bleWatvher = new BluetoothLEAdvertisementWatcher();
DeviceWatcher devWatcher = DeviceInformation.CreateWatcher(BluetoothLEDevice.GetDeviceSelector(), null);
public MainPage()
{
this.InitializeComponent();
Bloos = new ObservableCollection<BlooDevice>();
startScanner();
}
private void startScanner()
{
bleWatvher.Received += BleWatvher_Received;
bleWatvher.Stopped += BleWatvher_Stopped;
devWatcher.Added += DevWatcher_Added;
devWatcher.EnumerationCompleted += DevWatcher_EnumerationCompleted;
devWatcher.Removed += DevWatcher_Removed;
devWatcher.Stopped += DevWatcher_Stopped;
devWatcher.Updated += DevWatcher_Updated;
bleWatvher.Start();
Debug.WriteLine(Bloos.Count);
}
private void DevWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate args)
{
}
private void DevWatcher_Stopped(DeviceWatcher sender, object args)
{
devWatcher.Start();
}
private void DevWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
{
}
private void DevWatcher_EnumerationCompleted(DeviceWatcher sender, object args)
{
}
private void DevWatcher_Added(DeviceWatcher sender, DeviceInformation args)
{
}
private void BleWatvher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args)
{
bleWatvher.Start();
}
public ObservableCollection<BlooDevice> Bloos
{
get;
set;
}
private async void BleWatvher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var exists = Bloos.Where(b => b.BluetoothAddress == args.BluetoothAddress).ToList();
if (exists.Count == 0)
{
Bloos.Add(new BlooDevice
{
Name = args.Advertisement.LocalName,
Rssi = args.RawSignalStrengthInDBm,
BluetoothAddress = args.BluetoothAddress
});
}
else
{
exists.ForEach(delegate (BlooDevice e)
{
e.BluetoothAddress = args.BluetoothAddress;
e.Name = args.Advertisement.LocalName;
e.Rssi = args.RawSignalStrengthInDBm;
});
}
});
}
}
}
XAML 代码如下
<Page
x:Class="BleScanner.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BleScanner"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" RequestedTheme="Dark">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="10,40,0,0" >
<Image Source="assets/ble_bw.png" Width="64" Height="64" VerticalAlignment="Center"/>
<TextBlock Text="Ble Scanner" FontSize="24" FontWeight="Bold" VerticalAlignment="Center" Margin="20,0,0,0"></TextBlock>
</StackPanel>
<Border Margin="10,10,10,10" Grid.Row="1" BorderBrush="AntiqueWhite" BorderThickness="1">
<ListView ItemsSource="{x:Bind Bloos}" >
<ListView.Template>
<ControlTemplate>
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ListView.Template>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="256"></ColumnDefinition>
<ColumnDefinition Width="128"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Grid.Column="0"/>
<TextBlock Text="{Binding Rssi}" Grid.Column="1"/>
<TextBlock Text="{Binding BluetoothAddressHex}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Border >
</Grid>
</Page>
运行效果如图
源代码github地址
https://github.com/dingbig/BleScanner
相关的电路图