天天看點

windows phone 8中使用藍牙

在應用到應用的通信中,應用使用藍牙發現另一播發該應用想要通路的服務的應用。如果應用找到範圍内的提供此服務的另一應用,則發起連接配接請求。當兩個應用均接受連接配接時,将在兩者之間打開流套接字,應用通過它進行通訊。(應用應該是相同)

藍牙API,windows phone 8擴充: PeerFinder 提供發現附近裝置上的另一應用執行個體的能力,并在這些對等方應用之間建立套接字連接配接。對等方應用是運作在另一裝置上的另一應用執行個體。

PeerInformation

包含辨別對等應用或裝置的資訊。

StreamSocket

支援使用 TCP 流套接字的網絡通信。

ConnectionRequestedEventArgs 包含通過 ConnectionRequested 事件傳遞給應用的屬性。

在WMAppManifest.xml 中指定: 應用到應用 ID_CAP_PROXIMITY

應用到裝置

ID_CAP_PROXIMITY、ID_CAP_NETWORKING

一下代碼是綜合這兩個資料自己寫的,林政的代碼有點問題,msdn上有個地方有不同意見。

定義全局變量         StreamSocket  _socket;        //socket資料流對象          DataWriter  _dataWriter;      //資料寫入對象,将資料寫入到輸出流          DataReader  _dataReader;      //資料讀取對象,從輸入流中讀取資料

protected   override   void  OnNavigatedTo(   NavigationEventArgs  e)         {              base  .OnNavigatedTo(e);

             //一定要在FindAllPeersAsync之前調用,顯示自己的藍牙,讓别人能發現              PeerFinder  .Start();              //遠端對等類使用ConnectAsync時發生              PeerFinder  .ConnectionRequested+=PeerFinder_ConnectionRequested;         }

         protected   override   void  OnNavigatedFrom(   NavigationEventArgs  e)         {              base  .OnNavigatedFrom(e);

             PeerFinder  .ConnectionRequested -= PeerFinder_ConnectionRequested;              //stop:節約電量,避免像在程式中打開藍牙,傳回鍵回來目前頁面時能正确提示,而不會一直顯示打開藍牙             CloseConnection(   false  );         }

點選搜尋的時候調用 private   async   void  Search_Click(   object  sender,  RoutedEventArgs   e)         {              try             {                  //找到所有的                  var  peers =  await   PeerFinder .FindAllPeersAsync();                  if  (peers.Count == 0)                 {                      MessageBox  .Show( "沒有可以對接的應用"   );                 }                  else                 {                     listbox.ItemsSource = peers;

                     if  (listbox.Items.Count == 1)                         listbox.SelectedIndex = 0;                 }             }              catch  ( Exception   ex)             {                  if  (( uint   )ex.HResult == 0x8007048F)                 {                      var  result =  MessageBox   .Show(  "是否打開藍牙開關"  ,  "藍牙"   ,  MessageBoxButton  .OKCancel);                      if  (result ==  MessageBoxResult   .OK)                     {                          //打開藍牙設定                          ConnectionSettingsTask  connectionSettingsTask =  new   ConnectionSettingsTask ();                         connectionSettingsTask.ConnectionSettingsType =  ConnectionSettingsType  .Bluetooth;                         connectionSettingsTask.Show();                     }                 }                  else                 {                      MessageBox  .Show(ex.Message);                 }             }         }

點選連接配接的時候調用 private   void   OnLink(  object  sender,  RoutedEventArgs  e)         {              Button  btn = sender  as   Button ;              PeerInformation  peerInfo = btn.DataContext  as   PeerInformation ;

            ConnectToPeer(peerInfo);         }

建立連接配接套接字

private   async   void  ConnectToPeer(   PeerInformation  peer)         {              try             {                  //連接配接到一個對等類                 _socket =  await   PeerFinder   .ConnectAsync(peer);

                 // We can preserve battery by not advertising our presence.                  PeerFinder  .Stop();                  //讀取資訊                 PeerFinder_StartReader();             }              catch             {                  MessageBox  .Show( "目标主機未開啟"   );                  //msdn上是false,個人覺得應該為true                 CloseConnection(   true  );             }         }

在調用 ConnectAsync時會觸發事件,調用該事件委托

private   void   PeerFinder_ConnectionRequested(  object  sender,  ConnectionRequestedEventArgs  args)         {              this  .Dispatcher.BeginInvoke(() =>                 {                      try                     {                          var  result =  MessageBox   .Show(  string .Format(   "是否接受{0}的連結請求"   , args.PeerInformation.DisplayName),  "對接"   ,  MessageBoxButton .OKCancel);                          if  (result ==  MessageBoxResult   .OK)                         {                             txtshow.Text +=  "開始chat\n"   ;                             ConnectToPeer(args.PeerInformation);                         }                          else                         {                         }                     }                      catch  ( Exception   ex)                     {                          MessageBox  .Show(ex.Message);                         CloseConnection(   true  );       //重置                     }                 });         }

讀取資訊,時刻等待,異步 async   void   PeerFinder_StartReader()         {              try             {                  var  message =  await   GetMessage();                 txtshow.Text += message;                 PeerFinder_StartReader();             }              catch             {                  MessageBox  .Show( "讀出資料不正确"   );                 CloseConnection(   true  );                 txtshow.Text +=  "\nchat End!"  ;             }         }

         private   async   Task <   string  > GetMessage()         {              if  (_dataReader ==  null   )                 _dataReader =  new   DataReader   (_socket.InputStream);

             await  _dataReader.LoadAsync( sizeof   (  uint ));              uint  strLength = ( uint   )_dataReader.ReadInt32();      //讀出消息的長度              await  _dataReader.LoadAsync(strLength);              return  _dataReader.ReadString(strLength);            //讀出的字元串         }

發送資訊。 private   void   SendMessage_Tap_1(  object  sender, System.Windows.Input.   GestureEventArgs  e)         {             SendMessage(txtMessage.Text);         }

         private   async   void  SendMessage(   string  message)         {              if  (message.Trim().Length == 0)             {                  MessageBox  .Show( "輸入為空"   );                  return  ;             }

             if  (_socket ==  null   )             {                  MessageBox  .Show( "Socket Error"   );                  return  ;             }              if  (_dataWriter ==  null   )                 _dataWriter =  new   DataWriter   (_socket.OutputStream);              //寫入資訊的長度             _dataWriter.WriteInt32(message.Length);              await  _dataWriter.StoreAsync();              //寫入的字元串             _dataWriter.WriteString(message);              await  _dataWriter.StoreAsync();         }

主界面: <  Grid  x   :  Name ="ContentPanel"   Grid.Row  ="1"  Margin   ="12,0,12,0">              <  StackPanel >                  <  Button  Content   ="通過藍牙查找應用裝置"   HorizontalAlignment  ="Center"  VerticalAlignment ="Top"   Click  ="Search_Click"/>                  <  ListBox  Name   ="listbox">                      <  ListBox.ItemTemplate >                          <  DataTemplate >                              <  StackPanel  Orientation   ="Horizontal">                                  <  TextBlock  Text   ="{  Binding  DisplayName   }"/>                                  <  TextBlock  Text   ="{  Binding  ServiceName   }"/>                                  <  Button  Content   ="連結"  Width ="308"   Height  ="91"     VerticalAlignment  ="Top"  Click ="OnLink"/>                              </  StackPanel >                          </  DataTemplate >                      </  ListBox.ItemTemplate >                  </  ListBox >                  <  StackPanel  Orientation   ="Horizontal">                      <  TextBox  x   :  Name ="txtMessage"   Width  ="350"/>                      <  Button  x   :  Name ="btnSendMessage"   Content  ="Send"  Tap   ="SendMessage_Tap_1"/>                  </  StackPanel >                  <  TextBlock  Name   ="txtshow"/>              </  StackPanel >          </  Grid >

參考資料: http://www.cnblogs.com/linzheng/archive/2013/01/12/2857468.html http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj207007(v=vs.105).aspx