设为首页 收藏本站
查看: 845|回复: 0

[经验分享] Windows Phone 8 蓝牙编程

[复制链接]

尚未签到

发表于 2018-6-15 11:49:47 | 显示全部楼层 |阅读模式
  《深入浅出Windows Phone 8应用开发》之蓝牙编程
  蓝牙是手机的近距离无限传输的技术,在之前的Windows Phone 7系统手机里面仅支持蓝牙耳机功能,并不支持蓝牙文件信息传输,那么在Windows Phone 8手机里面将全面支持蓝牙技术,并且提供了相关的API来给开发者使用。开发者可以利用蓝牙的相关API来创建应用程序,在应用程序里面使用手机的蓝牙技术来进行近距离的文件传输和发送接收消息,创造出更加有趣和方便的应用软件。
  在Windows Phone 8里面可以在应用程序里面利用蓝牙进行通信,使用蓝牙相关的API,可以让应用程序连接到另外的一个应用程序,也可以让应用程序连接到一个设备上。Windows Phone 8的蓝牙技术支持两个蓝牙方案:一个是应用程序到应用程序的通信,另外一个是应用程序到设备的通信。
  1.应用程序到应用程序的通信
  应用程序到应用程序的通信的过程是,应用程序使用蓝牙去查找正在广播蓝牙服务的对等的应用程序,如果在应用程序提供服务的范围内发现一个应用程序,那么该应用程序可以发起连接请求。当这两个应用程序接受连接,它们之间就可以进行通信了,通信的过程是使用socket的消息发送接收机制。在Windows Phone 8中使用到应用程序到应用程序的蓝牙通讯技术,需要在项目的WMAppManifest.xml文件中添加ID_CAP_PROXIMITY的功能选项,表示支持临近的设备通信能力,否则程序会出现异常。
  2.应用程序到设备的通信
  在应用程序到设备的通信过程时,应用程序使用蓝牙去查找提供服务的设备,如果提供的服务范围之内发现一个可以连接的蓝牙设备,那么该应用程序可以发起连接请求。当应用程序和设备同时接受该连接,它们之间就可以进行通信了,通信的过程也是使用socket的消息发送接收机制,类似于应用程序到应用程序的通信。在Windows Phone 8中使用到应用程序到设备的蓝牙通讯技术,需要在项目的WMAppManifest.xml文件中添加ID_CAP_PROXIMITY和ID_CAP_NETWORKING的功能选项,表示支持临近的设备通信能力和网络通信能力,否则程序会出现异常。

蓝牙编程类
  在Windows Phone 8里面使用到蓝牙编程主要会用到PeerFinder类,PeerInformation类,StreamSocket类和ConnectionRequestedEventArgs类,这些类的说明如表19.1所示。因为蓝牙也是基于TCP协议进行消息传递了,所以需要用到Socket的相关的编程知识,以及StreamSocket类。PeerFinder类是蓝牙查找类,它的主要成员如表19.2所示。
  表19.1 蓝牙编程类的说明
  类名
  说明
  PeerFinder
  用于去查找附近的设备是否有运行和当前应用程序相同的应用程序,并且可以在两个应用程序之间建立起socket连接,从而可以进行通信。对等应用程序是在其他设备上运行的应用程序的另一个实例。
  PeerInformation
  包含对等应用程序或设备的识别信息。
  StreamSocket
  支持使用一个TCP的Socket流的网络通信。
  ConnectionRequestedEventArgs
  表示传递到一个应用程序的ConnectionRequested事件的属性
  表 19.2 PeerFinder类的成员
  成员
  说明
  bool   AllowBluetooth
  指定 PeerFinder 类的此实例是否可以通过使用 Bluetooth 来连接   ProximityStreamSocket 对象。如果PeerFinder 的此实例可以通过使用   Bluetooth 来连接 ProximityStreamSocket 对象,则为   true;否则为false。默认为   true。
  bool    AllowInfrastructure
  是否使用TCP/IP协议连接到StreamSocket
  bool   AllowWiFiDirect
  指定 PeerFinder 类的此实例是否可以通过使用 Wi-Fi Direct 来连接   ProximityStreamSocket 对象。如果 PeerFinder 的此实例可以通过使用   Wi-Fi Direct 来连接 ProximityStreamSocket 对象,则为   true;否则为false。默认为   true。

  IDictionary<string,   string>>  获取要与其他平台上的对等应用程序匹配的备用 AppId 值列表。返回要与其他平台的对等类应用程序匹配的备用 AppId 值列表。
  string   DisplayName
  获取或设置标识计算机到远程对等类的名称。
  PeerDiscoveryTypes   SupportedDiscoveryTypes
  获取一个值,该值指示哪些发现选项可与 PeerFinder 类一同使用
  event   TypedEventHandler<object, ConnectionRequestedEventArgs>   ConnectionRequested
  远程对等类使用 ConnectAsync 方法请求连接时发生。
  event   TypedEventHandler<object, TriggeredConnectionStateChangedEventArgs>   TriggeredConnectionStateChanged
  在远程对等类的轻击笔势期间发生。
  IAsyncOperation<   StreamSocket> ConnectAsync(PeerInformation peerInformation)
  连接已发现了对 FindAllPeersAsync 方法的调用的对等类。peerInformation:表示连接到的对等类的对等类信息对象。返回通过使用所提供的临近StreamSocket 对象连接远程对等类的异步操作。
  IAsyncOperation<IReadOnlyList<PeerInformation>>   FindAllPeersAsync()
  适用于无线范围内运行相同应用程序的对等计算机的异步浏览。返回通过使用 Wi-Fi直连技术浏览对等类的异步操作。
  void   Start(string peerMessage)
  向临近设备上的对等类应用程序传递消息。
  void   Stop()
  停止查找对等类应用程序或广播对等类连接的过程

查找蓝牙设备和对等项
  查找在服务范围内的蓝牙设备和对等项是蓝牙编程的第一步,查找蓝牙设备和对等项中会使用到PeerFinder类的FindAllPeersAsync方法去进行查找,然后以异步的方式返回查找到的对等项列表的信息IReadOnlyList<PeerInformation>,注意要使查找对等的应用程序时,在调用FindAllPeersAsync方法前必须先调用PeerFinder类的Start方法,主要的目的是启动广播服务,让对方的应用程序也能查找到自己。PeerInformation包含三个属性:一个是DisplayName表示对等项的名字,这个名字一般都是由对方的设备的名称或者查找到的应用程序自身设置的现实名字,一个是HostName表示主机名字或者IP地址,还有一个属性是ServiceName表示服务名称或者TCP协议的端口号。然后可以利用查找到的PeerInformation信息进行连接和通信。
  查找对等的应用程序的代码示例:
  


  • async void AppToApp()
  • {
  •     // 启动查找服务
  •     PeerFinder.Start();
  •     //开始查找
  •     ObservableCollection<PeerInformation> peers = await PeerFinder.FindAllPeersAsync();
  •     if (peers.Count == 0)
  •     {
  •         //未找到任何的对等项
  •     }
  •     else
  •     {
  •         //处理查找到的对等项,可以使用PeerFinder类的ConnectAsync方法来连接选择的要进行通信的对等项
  •     }
  • }
  

  查找蓝牙设备的代码示例:
  


  • private async void AppToDevice()
  • {
  •     // 设置查找所匹配的蓝牙设备
  •     PeerFinder.AlternateIdentities[&quot;Bluetooth:Paired&quot;] = &quot;&quot;;
  •     // 开始查找
  •     ObservableCollection<PeerInformation> pairedDevices = await PeerFinder.FindAllPeersAsync();
  •     if (pairedDevices.Count == 0)
  •     {
  •         // 没有找到可用的蓝牙设备
  •     }
  •     else
  •     {
  •         //处理查找到的蓝牙设备,可以新建一个StreamSocket对象,然后使用StreamSocket类的ConnectAsync方法通过HostName和ServiceName来连接蓝牙设备
  •     }
  • }
  

蓝牙发送消息
  蓝牙编程的发送消息机制使用的是TCP的StreamSocket的方式,原理与Socket的一致。在蓝牙连接成功后,可以获取到一个StreamSocket类的对象,然后我们使用该对象的OutputStream属性来初始化一个DataWriter对象,通过DataWriter对象来进行发送消息。OutputStream属性表示的是Socket的输出流,用于发送消息给对方。下面来看一下发送消息的示例:
  


  • async void SendMessage(string message)
  • {
  •     // 连接选中的对等项,selectedPeer为查找到的PeerInformation对象
  •     StreamSocket _socket= = await PeerFinder.ConnectAsync(selectedPeer);
  •     // 创建DataWriter
  •     DataWriter _dataWriter = new DataWriter(_socket.OutputStream);
  •     // 先写入发送消息的长度
  •      _dataWriter.WriteInt32(message.Length);
  •      await _dataWriter.StoreAsync();
  •     // 最后写入发送消息的内容
  •      _dataWriter.WriteString(message);
  •      await _dataWriter.StoreAsync();
  • }
  

蓝牙接收消息
  蓝牙编程的接收消息机制同样也是使用的是TCP的StreamSocket的方式,原理与Socket的一致。在蓝牙连接成功后,可以获取到一个StreamSocket类的对象,然后我们使用该对象的InputStream属性来初始化一个DataReader对象,通过DataReader对象来进行接收消息。InputStream属性表示的是Socket的输入流,用于接收对方的消息。下面来看一下接收消息的示例:
  


  • async Task<string> GetMessage()
  • {
  •     // 连接选中的对等项,selectedPeer为查找到的PeerInformation对象
  •     StreamSocket _socket= = await PeerFinder.ConnectAsync(selectedPeer);
  •     // 创建DataReader
  •     DataReader _dataReader = new DataReader(_socket.InputStream);
  •     // 先读取消息的长度
  •     await _dataReader.LoadAsync(4);
  •     uint messageLen = (uint)_dataReader.ReadInt32();
  •     // 最后读取消息的内容
  •     await _dataReader.LoadAsync(messageLen);
  •     return _dataReader.ReadString(messageLen);
  • }
  

实例:实现蓝牙程序对程序的传输
  下面给出蓝牙程序对程序传输的示例:通过使用蓝牙功能查找周边也要使用改应用的手机,互相建立起连接和发送测试消息。
  
代码清单19-1:蓝牙程序对程序传输(源代码:第19章\Examples_19_1)
  MainPage.xaml文件主要代码
  


  • <Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;>
  •   <StackPanel>
  •     <Button x:Name=&quot;btFindBluetooth&quot; Content=&quot;通过蓝牙查找该应用设备&quot; Click=&quot;btFindBluetooth_Click&quot;/>
  •     <ListBox x:Name=&quot;lbBluetoothApp&quot;  ItemsSource=&quot;{Binding}&quot; >
  •       <ListBox.ItemTemplate >
  •         <DataTemplate>
  •           <StackPanel>
  •             <TextBlock  Text=&quot;{Binding DisplayName}&quot; />
  •             <TextBlock  Text=&quot;{Binding ServiceName}&quot; />
  •             <Button Content=&quot;连接&quot; HorizontalAlignment=&quot;Left&quot; Width=&quot;308&quot; Height=&quot;91&quot; Click=&quot;btConnect_Click&quot;/>
  •           </StackPanel>
  •         </DataTemplate>
  •       </ListBox.ItemTemplate>
  •     </ListBox>
  •   </StackPanel>
  • </Grid>
  

  MainPage.xaml.cs文件主要代码
  


  • using System;
  • using System.Windows;
  • using System.Windows.Controls;
  • using Microsoft.Phone.Controls;
  • using Windows.Networking.Proximity;
  • using Windows.Networking.Sockets;
  • using Windows.Storage.Streams;
  • namespace BluetoothDemo
  • {
  •     public partial class MainPage : PhoneApplicationPage
  •     {
  •         private StreamSocket _socket = null;  // Socket数据流对象
  •         private DataWriter _dataWriter;  // 数据写入对象
  •         private DataReader _dataReader; // 数据读取对象
  •         public MainPage()
  •         {
  •             InitializeComponent();
  •             Loaded += MainPage_Loaded;//页面加载事件
  •         }
  •         // 查找蓝牙对等项按钮事件处理
  •         private async void btFindBluetooth_Click(object sender, RoutedEventArgs e)
  •         {
  •             try
  •             {
  •                 //开始查找对等项
  •                 PeerFinder.Start();
  •                 // 等待找到的对等项
  •                 var peers = await PeerFinder.FindAllPeersAsync();
  •                 if (peers.Count == 0)
  •                 {
  •                     MessageBox.Show(&quot;没有发现对等的蓝牙应用&quot;);
  •                 }
  •                 else
  •                 {
  •                     // 把对等项目绑定到列表中
  •                     lbBluetoothApp.ItemsSource = peers;
  •                 }
  •             }
  •             catch(Exception ex)
  •             {
  •                 if ((uint)ex.HResult == 0x8007048F)
  •                 {
  •                     MessageBox.Show(&quot;Bluetooth已关闭请打开手机的蓝牙开关&quot;);
  •                 }
  •                 else
  •                 {
  •                     MessageBox.Show(ex.Message);
  •                 }
  •             }
  •         }
  •         // 连接蓝牙对等项的按钮事件处理
  •         private async void btConnect_Click(object sender, RoutedEventArgs e)
  •         {
  •             Button deleteButton = sender as Button;
  •             PeerInformation selectedPeer = deleteButton.DataContext as PeerInformation;
  •             // 连接到选择的对等项
  •             _socket = await PeerFinder.ConnectAsync(selectedPeer);
  •             // 使用输出输入流建立数据读写对象
  •             _dataReader = new DataReader(_socket.InputStream);
  •             _dataWriter = new DataWriter(_socket.OutputStream);
  •             // 开始读取消息
  •             PeerFinder_StartReader();
  •         }
  •         // 读取消息
  •         async void PeerFinder_StartReader()
  •         {
  •             try
  •             {
  •                 uint bytesRead = await _dataReader.LoadAsync(sizeof(uint));
  •                 if (bytesRead > 0)
  •                 {
  •                     // 获取消息内容的大小
  •                     uint strLength = (uint)_dataReader.ReadUInt32();
  •                     bytesRead = await _dataReader.LoadAsync(strLength);
  •                     if (bytesRead > 0)
  •                     {
  •                         String message = _dataReader.ReadString(strLength);
  •                         MessageBox.Show(&quot;获取到消息:&quot; + message);
  •                         // 开始下一条消息读取
  •                         PeerFinder_StartReader();
  •                     }
  •                     else
  •                     {
  •                         MessageBox.Show(&quot;对方已关闭连接&quot;);
  •                     }
  •                 }
  •                 else
  •                 {
  •                     MessageBox.Show(&quot;对方已关闭连接&quot;);
  •                 }
  •             }
  •             catch (Exception e)
  •             {
  •                 MessageBox.Show(&quot;读取失败: &quot; + e.Message);
  •             }
  •         }
  •         // 页面加载事件处理
  •         void MainPage_Loaded(object sender, RoutedEventArgs e)
  •         {
  •             // 订阅连接请求事件
  •             PeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;
  •         }
  •         // 连接请求事件处理
  •         void PeerFinder_ConnectionRequested(object sender, ConnectionRequestedEventArgs args)
  •         {
  •             // 连接并且发送消息
  •             ConnectToPeer(args.PeerInformation);
  •         }
  •         // 连接并发送消息给对方
  •         async void ConnectToPeer(PeerInformation peer)
  •         {
  •             _socket = await PeerFinder.ConnectAsync(peer);
  •             _dataReader = new DataReader(_socket.InputStream);
  •             _dataWriter = new DataWriter(_socket.OutputStream);
  •             string message = &quot;测试消息&quot;;
  •             uint strLength = _dataWriter.MeasureString(message);
  •             _dataWriter.WriteUInt32(strLength);//写入消息的长度
  •             _dataWriter.WriteString(message);//写入消息的内容
  •             uint numBytesWritten = await _dataWriter.StoreAsync();
  •         }
  •     }
  • }
  

  程序的运行效果如图19.2所示。
DSC0000.png


实例:实现蓝牙程序对设备的连接

下面给出蓝牙程序对设备连接的示例:查找蓝牙设备,并对找到的第一个蓝牙设备进行连接。

  
代码清单19-2:蓝牙程序对设备连接(源代码:第19章\Examples_19_2)
  MainPage.xaml文件主要代码
  


  • <Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;>
  •      <StackPanel>
  •         <Button x:Name=&quot;btFindBluetooth&quot; Content=&quot;连接周围的蓝牙设备&quot; Click=&quot;btFindBluetooth_Click&quot;/>
  •     </StackPanel>
  • </Grid>
  

  MainPage.xaml.cs文件主要代码
  


  • // 查找蓝牙设备事件处理
  • private async void btFindBluetooth_Click(object sender, RoutedEventArgs e)
  • {
  •      try
  •      {
  •          // 配置PeerFinder蓝牙服务的GUID去搜索设备
  •          PeerFinder.AlternateIdentities[&quot;Bluetooth:SDP&quot;] = &quot;5bec6b8f-7eba-4452-bf59-1a510745e99d&quot;;
  •          var peers = await PeerFinder.FindAllPeersAsync();
  •          if (peers.Count == 0)
  •          {
  •              Debug.WriteLine(&quot;没发现蓝牙设备&quot;);
  •          }
  •          else
  •          {
  •              // 连接找到的第一个蓝牙设备
  •              PeerInformation selectedPeer = peers[0];
  •              StreamSocket socket = new StreamSocket();
  •              await socket.ConnectAsync(selectedPeer.HostName, selectedPeer.ServiceName);
  •              MessageBox.Show(&quot;连接上了HostName:&quot; + selectedPeer.HostName + &quot;ServiceName:&quot; + selectedPeer.ServiceName);
  •          }
  •      }
  •      catch (Exception ex)
  •      {
  •          if ((uint)ex.HResult == 0x8007048F)
  •          {
  •              MessageBox.Show(&quot;Bluetooth is turned off&quot;);
  •          }
  •      }
  • }
  

  程序的运行效果如图19.3所示
DSC0001.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-524182-1-1.html 上篇帖子: Windows Vista下的EFS加密 下篇帖子: 2012年度博客大赛之我见
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表