本文章是由機器翻譯。

通用應用程式

為您的應用程式添加 OBEX 功能

Uday Gupta

下載代碼示例

在過去的十年,Bluetooth已經成為一種常用的技術,為手機、 個人電腦和耳機等設備之間的短距離無線通訊。Bluetooth特殊興趣組 (BTSIG) 是在Bluetooth設定檔規範中定義的標準無線服務的行業組織。

一種設定檔是物件推送設定檔 (OPP),用於從一個設備向另一個發送檔。物件切換式通訊協定 (OBEX) 是基礎的交往的一部分OBEX 是也用作非 OPP,設定檔中它是通用的協定,用於設備間傳輸物件。

對於開發人員希望在他們的應用程式內使用 OBEX,我已經在內部應用程式在 Windows 運行時 (WinRT)BluetoothApi,提供從 OBEX 制定一套 Api。這些 Api 來作為一個庫包通用的應用程式,這意味著 Windows 應用商店應用程式和 Windows Phone Silverlight 應用程式可以利用相同的 Api 集。

OBEX 和 OPP

首先,它是重要的是瞭解 OBEX 和 OPP 是什麼以及它們是如何工作。OPP 允許將一個檔或物件發送到另一個 OPP 能夠Bluetooth設備的Bluetooth設備。OBEX 的用途是通過紅外通道共用的檔。BTSIG 選擇重用本議定書對檔通過Bluetooth共用。除了底層的傳輸介質,OBEX 紅外線結束與 OBEX-以上-Bluetooth相近。

OBEX 基於收件者的Bluetooth設備正在運行 OBEX 伺服器偵聽並接受用戶端連接的用戶端-伺服器模型。作為一種流管道通過Bluetooth一事外,用戶端Bluetooth設備連接到伺服器的Bluetooth設備。允許連接和物件傳輸的身份驗證要求取決於該服務或應用程式使用 OBEX。例如,OPP 可以允許未經身份驗證的連接,以簡化快速交換名片的過程。其他服務使用 OBEX 可能只允許已通過身份驗證的連接。

檔共用使用三種類型的資料包。這些資料包被稱為第一放,中間投入和最後投入。第一個把資料包標記檔案傳輸初始化並最後把包標誌著它完成。多個中間放資料包包含大量資料。伺服器接收到付諸表決的每個資料包後,它會將確認資料包返回用戶端。

在典型的場景中,OBEX 資料包發送,如下所示:

  1. OBEX 用戶端連接到該收件者的設備發送一個連接資料包。此資料包指定的最大資料包大小用戶端可以接收。
  2. 接收來自伺服器指示連接的回應已被接受後 OBEX 用戶端發送第一個把資料包。這包含的中繼資料描述的物件,包括檔的名稱和大小。(雖然 OBEX 協定允許這第一把包還包括物件的資料,庫已經開發了 OBEX 執行不任何資料第一次放在資料包中發送。)
  3. 接收確認伺服器已第一次把資料包之後,OBEX 用戶端發送包含物件資料的多個把資料包。這些資料包的長度被有限的伺服器能夠接收,通過伺服器的回應連接資料包發送的第一步中設置的最大資料包大小。
  4. 最後把資料包中包含最後提出恒定和最終資料塊分配的物件。
  5. 檔共用一旦完成,OBEX 用戶端發送一個斷開連接的資料包,並關閉Bluetooth連接。OBEX 協定允許重複步驟兩到三個在同一連接上發送多個物件。

在任何時刻,OBEX 用戶端可以通過發送中止資料包終止共用的過程。立即取消共用。在圖書館裡我已經寫了,OBEX 協定實現細節隱藏的您將僅看到高級 Api。

OBEX 圖書館

BluetoothOBEX 用戶端圖書館為 Windows 應用商店應用程式被設計為可擕式圖書館針對:Windows 應用商店應用程式和 Windows Phone Silverlight 8.1 的應用程式。它包含三個 Dll,以使圖書館運行時的 OBEX 用戶端。每個 DLL 被設計來處理特定的任務:Bluetooth。Core.Service,Bluetooth。Core.Sockets 和Bluetooth。Services.Obex。

Bluetooth核心服務Bluetooth檔。Core.Service.dll 包含Bluetooth。Core.Service 命名空間。此庫的目的是尋找和與用戶端設備附近的Bluetooth設備配對的計數 (見圖 1)。目前,它僅限於配對設備一次性計數。未來的版本將包含一個觀察者繼續尋找其他的Bluetooth設備。

圖 1 的方法和相關的活動,從 BluetoothService

(帶有參數) 的方法 相關的事件
[靜態]GetDefault 沒有關聯的事件
SearchForPairedDevicesAsync

成功-SearchForDevicesSucceeded

失敗-SearchForPairedDevicesFailed

Bluetooth服務的核心由一個名為 BluetoothService,所示的靜態類圖 2。此類具有一個 API 來非同步計數裝置。

圖 2 BluetoothService 計數配對設備

BluetoothService btService = BluetoothService.GetDefault();
btService.SearchForPairedDevicesFailed 
  += btService_SearchForPairedDevicesFailed;
btService.SearchForPairedDevicesSucceeded 
  += btService_SearchForPairedDevicesSucceeded;
await btService.SearchForPairedDevicesAsync();
void btService_SearchForPairedDevicesSucceeded(object sender,
  SearchForPairedDevicesSucceededEventArgs e)
{
  // Get list of paired devices from e.PairedDevices collection
}
void btService_SearchForPairedDevicesFailed(object sender,
  SearchForPairedDevicesFailedEventArgs e)
{
  // Get the failure reason from e.FailureReason enumeration
}

Bluetooth芯插座Bluetooth檔。Core.Sockets.dll 包含Bluetooth。Core.Sockets 命名空間,旨在通過Bluetooth連接支援基於流通訊端操作。通過 BluetoothSockets 類公開的插座功能 (請參閱圖 3)。這是 TCP 既 UDP 通訊端。與收件者的設備的所有通信通過 BluetoothSockets 都發生。

圖 3 方法和相關的活動,從 BluetoothSockets

(帶有參數) 的方法 相關的事件

建構函式 (Bluetooth。) Core.Services.BluetoothDevice

建構函式 (Bluetooth。Core.Services.BluetoothDevice,System.UInt32)

建構函式 (Bluetooth。Core.Services.BluetoothDevice,System.String)

建構函式 (Bluetooth。Core.Services.BluetoothDevice,System.UInt32,System.String)

沒有關聯的事件
PrepareSocketAsync

成功 — — SocketConnected

失敗 — — ErrorOccured

SendDataAsync(System.Byte[])

SendDataAsync(System.String)

沒有關聯的事件
接字 SocketClosed
沒有關聯的方法 DataReceived

Bluetooth服務 Obex Bluetooth。Services.Obex.DLL 檔案包含Bluetooth。Services.Obex 命名空間。這是通過一個名為 ObexService 類公開的 OBEX 核心實現。此類提供BluetoothOPP 規範的抽象的視圖。它公開的方法,可以説明連接、 發送和從收件者的Bluetooth設備斷開連接。圖 4 列出的 Api 和關聯的事件,此類公開,和圖 5 演示的用法。

圖 4 方法和相關的活動,從 ObexService

(帶有參數) 的方法 相關的事件
[靜態]GetDefaultForBluetoothDevice (Bluetooth。) Core.Services.BluetoothDevice 沒有關聯的事件
ConnectAsync

成功 — — DeviceConnected

失敗 — — ConnectionFailed

SendFileAsync(Windows.Storage.IStorageFile)

成功:

ServiceConnected

DataTransferProgressed

DataTransferSucceeded

斷開連接

已中斷連接

失敗:

ConnectionFailed

DataTransferFailed

AbortAsync 已中止

圖 5 Obex 服務使用方式

protected async override void OnNavigatedTo(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
  base.OnNavigatedTo(e);
  ObexService obexService = ObexService.GetDefaultForBluetoothDevice(null);
  obexService.DeviceConnected += obexService_DeviceConnected;
  obexService.ServiceConnected += obexService_ServiceConnected;
  obexService.ConnectionFailed += obexService_ConnectionFailed;
  obexService.DataTransferProgressed += obexService_DataTransferProgressed;
  obexService.DataTransferSucceeded += obexService_DataTransferSucceeded;
  obexService.DataTransferFailed += obexService_DataTransferFailed;
  obexService.Disconnecting += obexService_Disconnecting;
  obexService.Disconnected += obexService_Disconnected;
  obexService.Aborted += obexService_Aborted;
  await obexService.ConnectAsync();
}
async void obexService_DeviceConnected(object sender, EventArgs e)
{
  // Device is connected, now send file
  await (sender as ObexService).SendFileAsync(fileToSend);
}
void obexService_ServiceConnected(object sender, EventArgs e)
{
  // Device connected to Obex Service on target device
}
void obexService_ConnectionFailed(object sender, 
  ConnectionFailedEventArgs e)
{
  // Connection to service failed
}
void obexService_DataTransferProgressed(object sender, 
  DataTransferProgressedEventArgs e)
{
  // Get data transfer progress from DataTransferProgressedEventArgs
}
void obexService_DataTransferSucceeded(object sender, EventArgs e)
{
  // Data transfer succeeded
}
void obexService_DataTransferFailed(object sender, DataTransferFailedEventArgs e)
{
  // Data transfer failed, get the reason from DataTransferFailedEventArgs
}
void obexService_Disconnecting(object sender, EventArgs e)
{
  // Device is disconnecting from service
  }
void obexService_Disconnected(object sender, EventArgs e)
{
  // Device is now disconnected from targeted device and service
}
void obexService_Aborted(object sender, EventArgs e)
{
  // Data transfer operation is aborted
}

使用這些庫的典型的使用場景有點像這個樣子:

  • 使用 Api 中藍色-­牙。Core.Service,計數所有成對的 OPP 能夠Bluetooth設備。已實施 OPP 承載力驗算。
  • 獲取要與之共用檔的 BluetoothDevice 的實例。
  • 通過將 BluetoothDevice 的實例傳遞到工廠方法將 ObexService 的實例獲取收件者Bluetooth設備。ObexService 類內部將創建的 BluetoothSocket,而 ObexService 將共用該檔的一個實例。
  • 檔共用一旦完成,ObexService 是自動斷開連接。

開始使用

因為我的圖書館針對 Windows 應用商店應用程式和 Windows Phone 8.1 的應用程式,就會開始用一個通用的應用程式。這些是一個偉大的方式開發應用程式的所有 Windows 設備。若要瞭解關於通用應用程式的更多資訊,請訪問 bit.ly/1h3AQeu。要使用通用的應用程式啟動,我會使用Visual Studio2013年和創建一個新的通用應用程式專案的應用商店應用程式節點下 (見圖 6)。我用 Visual C#,但你也可以使用Visual Basic和 Visual c + +。

空白的通用應用程式來創建一個新專案
圖 6 空白的通用應用程式來創建一個新專案

一個BluetoothOBEX 客戶機應用程式的程式設計之前,我會更新 package.appx­(應用程式的 Windows 8.1 和 Windows Phone 8.1) 這兩個專案的清單檔:

<Capabilities>
  <m2:DeviceCapability Name="bluetooth.rfcomm">
    <m2:Device Id="any">
      <m2:Function Type="name:obexObjectPush"/>
    </m2:Device>
  </m2:DeviceCapability>
</Capabilities>

若要應用此更新,我打開 package.appx­­清單作為通過在解決方案資源管理器中的內容功能表中選擇查看代碼的代碼檔。我會的地方,這段代碼在哪裡 < 應用程式 > 標記結束。該代碼片段需要提供設備級能力與此應用程式使用Bluetooth無線射頻通信 (RFCOMM) 服務。我還指定所有服務和裝置類型與此設備相容。

對於我的場景,我需要 obexObjectPush 的支援從任何 OPP 能力的設備與相容的設備。有關 Windows 8.1 和 Windows Phone 8.1 支援設定檔的詳細資訊,請訪問 bit.ly/1pG6rYO。如果該功能沒有被提及,然後設備枚舉將失敗,並 CapabilityNotDefined 枚舉常量。

在開始編碼之前,我將添加對前面提到,所以我可以在這些庫中使用 OBEX 執行的三個庫檔的引用。我需要單獨對這些庫的這兩個專案增加參考。如果不增加參考,該專案將無法使用任何功能。

我跟著這些編碼的模式和做法:

  • 在 Windows 專案中實現 Windows 商店 8.1 應用程式的使用者體驗設計。
  • 在 Windows Phone 專案中實現 Windows Phone 8.1 應用程式的使用者體驗設計。
  • 在共用專案中實現共同的特點。
  • 在使用特定于平臺的編譯器常量的共用專案中執行特定于平臺的實現。對於 Windows 8.1,我將使用 WINDOWS_APP。對於 Windows Phone 8.1,我將使用 WINDOWS_PHONE_APP。這些編譯器常量已經被定義為專案的一部分。

下載的示例代碼,要使用這些庫,您應遵循開發通用的應用程式的編碼實踐和經驗。圖 7 顯示了樣例專案解決方案資源管理器視窗的檔結構和模式。

BluetoothDemo 應用程式的解決方案資源管理器圖
BluetoothDemo 應用程式的解決方案資源管理器圖 7

枚舉的配對的設備

可以分享是成對的設備的檔之前,我需要看到的配對設備清單中,選擇一個目標。我會把Bluetooth的實例的控制碼。Core.Services.BluetoothService,表示我的裝置所提供的Bluetooth服務的核心。我獲得使用 GetDefault 靜態工廠方法,此實例,因為只有一個Bluetooth服務可用的每個設備。

對枚舉,我要對 SearchForPairedDevicesAsync 方法的調用。此方法將開始枚舉設備與我的裝置配對。對於 Windows 商店 8.1 的應用程式,我需要允許使用的是成對的設備要枚舉的設備。如果我阻止使用,不會枚舉該配對的設備。

如果該 API 成功,它將引發 SearchForPairedDevicesSucceeded 事件,從其事件參數提取的配對設備的集合。否則,將引發 SearchForPairedDevicesFailed 事件,與故障枚舉常量在其事件參數中可用。圖 8 顯示枚舉設備的代碼。

圖 8 枚舉配對設備

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
  base.OnNavigatedTo(e);
  await EnumerateDevicesAsync();
}
public async Task EnumerateDevicesAsync()
{
  BluetoothService btService = BluetoothService.GetDefault();
  btService.SearchForPairedDevicesFailed +=
    btService_SearchForPairedDevicesFailed;
  btService.SearchForPairedDevicesSucceeded +=
    btService_SearchForPairedDevicesSucceeded;
  await btService.SearchForPairedDevicesAsync();
}
void btService_SearchForPairedDevicesSucceeded(object sender,
  SearchForPairedDevicesSucceededEventArgs e)
{
  (sender as BluetoothService).SearchForPairedDevicesFailed -=
    btService_SearchForPairedDevicesFailed;
  (sender as BluetoothService).SearchForPairedDevicesSucceeded -=
    btService_SearchForPairedDevicesSucceeded;
  this.cvBtDevices.Source = e.PairedDevices;
}
void btService_SearchForPairedDevicesFailed(object sender,
  SearchForPairedDevicesFailedEventArgs e)
{
  (sender as BluetoothService).SearchForPairedDevicesFailed -=
    btService_SearchForPairedDevicesFailed;
  (sender as BluetoothService).SearchForPairedDevicesSucceeded -=
    btService_SearchForPairedDevicesSucceeded;
  txtblkErrorBtDevices.Text = e.FailureReason.ToString();
}

我還提供了在 BottomAppBar 為 Windows 8.1 和 Windows Phone 8.1 為工作列中的掃描按鈕。這種方式的應用程式使用者可以重新掃描設備一旦到了一個新的配對的設備。

當枚舉上 Windows Phone 8.1 的設備,它將枚舉所有 OBEX 功能的設備,不管它們物理的存在以及是否開啟Bluetooth無線功能。然而,當枚舉上 Windows 8.1 的設備,它只會列出那些接近 Windows 8.1 設備,而且其Bluetooth無線功能開啟的物理存在的設備。

一旦我列舉配對的設備,我可以選擇一個設備共用檔。每個設備被表示為一個物件Bluetooth。Core.Services.BluetoothDevice 類。該物件包含連接的詳細資訊和配對的設備的顯示名稱。Bluetooth。內部 Services.Obex.ObexService 將使用連接的詳細資訊創建Bluetooth的一個實例。Core.Sock­ets。BluetoothSocket 和連接到配對的設備。

使用 ObexService

Bluetooth的實例的一旦。Core.Services.BluetoothDevice 物件,它表示我目標的設備共用檔,可以使用Bluetooth。共用檔使用西三環 Services.Obex.ObexService我還需要的檔的清單,所以我可以共用佇列。在代碼示例中,我只提供了少量的檔。否則,我可以使用 Windows.Storage.Pickers.FileOpenPicker (見 bit.ly/1qtiLeh) 或自訂的邏輯,從我的 Windows.Storage.ApplicationData.Current.LocalFolder (看到 bit.ly/1qtiSGI) 若要選擇多個檔。

到目前為止,我才可以共用一個檔,每個連接。完成共用時,將關閉與目標設備的連接。如果我需要發送多個檔,我需要獲得藍色的控制碼­牙。Services.Obex.ObexService 實例多次。我可以獲得此實例使用靜態工廠方法 GetDefaultForBluetoothDevice (Bluetooth。Core.Services.BluetoothDevice)。此方法返回Bluetooth的單個實例。表示 Obex 服務設備上的 Services.Obex.ObexService。

若要表示要共用的檔,我將使用 FileItemToShare 類。這包含的名稱、 路徑和檔的大小和 Windows.Storage.IStorageFile 的實例 (見 bit.ly/1qMcZlB) 表示磁片上的檔實例。我會排隊所有檔共用的資料結構物件。當共用多個檔,在清單中的第一個檔是當前正在共用。完成共用時,它是從清單中刪除。圖 9 演示如何掛鉤 ObexService 和其事件的共用檔。

圖 9 掛鉤 ObexService 和其事件

ObexService obexService = null;
BluetoothDevice BtDevice = null;
ObservableCollection<FileItemToShare> filesToShare = null;
async override void OnNavigatedTo(NavigationEventArgs e)
{
  base.OnNavigatedTo(e);
  if (e.Parameter == null || !(e.Parameter is BluetoothDevice))
  {
    MessageDialog messageBox = new MessageDialog(
      "Invalid navigation detected. Moving to Main Page", "Bluetooth Hub");
    messageBox.Commands.Add(new UICommand("OK", (uiCommand) =>
    {
      this.Frame.Navigate(typeof(MainPage));
    }));
    await messageBox.ShowAsync();
    return;
  }
  BtDevice = e.Parameter as BluetoothDevice;
  filesToShare = GetFilesFromLocalStorage();
  this.cvFileItems.Source = filesToShare;
  obexService = ObexService.GetDefaultForBluetoothDevice(BtDevice);
  obexService.Aborted += obexService_Aborted;
  obexService.ConnectionFailed += obexService_ConnectionFailed;
  obexService.DataTransferFailed += obexService_DataTransferFailed;
  obexService.DataTransferProgressed += obexService_DataTransferProgressed;
  obexService.DataTransferSucceeded += obexService_DataTransferSucceeded;
  obexService.DeviceConnected += obexService_DeviceConnected;
  obexService.Disconnected += obexService_Disconnected;
  obexService.Disconnecting += obexService_Disconnecting;
  obexService.ServiceConnected += obexService_ServiceConnected;
  await obexService.ConnectAsync();
}

當調用 ConnectAsync 方法時,ObexService 物件從 BluetoothDevice 物件,被傳遞到工廠方法中獲取的連接屬性。它試圖通過Bluetooth通道與目標 BluetoothDevice 創建連接。當那是成功的時它將引發 DeviceConnected 事件。圖 10 顯示 ObexService 的 DeviceConnected 事件處理常式。

圖 10 DeviceConnected 事件處理常式方法

async void obexService_DeviceConnected(object sender, EventArgs e)
{
  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
  {
    System.Diagnostics.Debug.WriteLine("device connected");
    if (filesToShare.Count > 0)
    {
      filesToShare.ShareStatus = FileShareStatus.Connecting;
      await obexService.SendFileAsync(filesToShare[0].FileToShare);
    }
    ...
  });
}

只要該設備連接到目標設備,我會開始共用索引 0 處的檔的清單檔。通過調用 SendFileAsync(Windows.Storage.IStorageFile) 和傳遞由 IStorageFile 從 FileToShare 資料結構類型的物件表示的檔物件共用檔。當調用此方法時,ObexService 嘗試連接到目標設備上運行的 OBEX 伺服器。如果連接不成功,它將引發 ServiceConnected 事件。否則,它將引發 ConnectionFailed 事件。此代碼演示 ServiceConnected 事件處理常式:

async void obexService_ServiceConnected(object sender, EventArgs e)
{
  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  {
    System.Diagnostics.Debug.WriteLine("service connected");
    filesToShare[0].ShareStatus = FileShareStatus.Sharing;
  });
}

圖 11 顯示 ObexService 的 ConnectionFailed 事件處理常式。

圖 11 ConnectionFailed 事件處理常式方法

async void obexService_ConnectionFailed(object sender, 
  ConnectionFailedEventArgs e)
{
  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
  {
    System.Diagnostics.Debug.WriteLine("connection failed");
    filesToShare[0].ShareStatus = FileShareStatus.Error;
    filesToShare[0].Progress = 0;
    FileItemToShare currentItem = filesToShare[0];
    filesToShare.RemoveAt(0);
    filesToShare.Add(currentItem);
  });
}

當我的裝置連接到目標設備的 OBEX 伺服器時、 檔共用過程就開始了。檔共用的進度可以確定從 DataTransferProgressed 事件。下面的代碼演示的 DataTransferProgressed 方法:

async void obexService_DataTransferProgressed(object sender,
  DataTransferProgressedEventArgs e)
{
  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  {
    System.Diagnostics.Debug.WriteLine("Bytes {0}, Percentage {1}",
      e.TransferInBytes, e.TransferInPercentage);
    filesToShare[0].Progress = e.TransferInBytes;
  });
}

一旦檔共用已完成的這就提出了資料傳輸­成功事件。如果檔共用是不成功的它提出了 DataTransferFailedEvent。下面的代碼演示資料傳輸­成功事件處理常式:

async void obexService_DataTransferSucceeded(object sender, EventArgs e)
{
  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  {
    System.Diagnostics.Debug.WriteLine("data transfer succeeded");
    filesToShare.RemoveAt(0);
  });
}

如果一個檔共用錯誤,它將引發 DataTransferFailed 事件。事件處理常式,如下面的代碼所示:

async void obexService_DataTransferFailed(object sender,
  DataTransferFailedEventArgs e)
{
  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
  {
    System.Diagnostics.Debug.WriteLine("Data transfer failed {0}",
      e.ExceptionObject.ToString());
    filesToShare[0].ShareStatus = FileShareStatus.Error;
    filesToShare[0].Progress = 0;
    FileItemToShare fileToShare = this.filesToShare[0];
    filesToShare.RemoveAt(0);
    this.filesToShare.Add(fileToShare);
  });
}

當資料傳輸完成後,從清單中刪除共用的檔和 ObexService 已中斷連線。當斷開連接 ObexService 時,它將引發斷開事件。而且,當正確地斷開連接,然後斷開連接的事件引發。斷開事件處理常式如下所示:

void obexService_Disconnecting(object sender, EventArgs e)
{
  System.Diagnostics.Debug.WriteLine("disconnecting");
}

一旦成功地斷開連接,在代碼圖 12 引發斷開連接的事件的控制碼。

圖 12 斷開連接事件處理常式方法

async void obexService_Disconnected(object sender, EventArgs e)
{
  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
  {
    System.Diagnostics.Debug.WriteLine("disconnected");
    obexService.Aborted -= obexService_Aborted;
    obexService.ConnectionFailed -= obexService_ConnectionFailed;
    obexService.DataTransferFailed -= obexService_DataTransferFailed;
    obexService.DataTransferProgressed -= 
      obexService_DataTransferProgressed;
    obexService.DataTransferSucceeded -= 
      obexService_DataTransferSucceeded;
    obexService.DeviceConnected -= obexService_DeviceConnected;
    obexService.Disconnected -= obexService_Disconnected;
    obexService.Disconnecting -= obexService_Disconnecting;
    obexService.ServiceConnected -= obexService_ServiceConnected;
    obexService = null;
    if (filesToShare.Count.Equals(0))
    {
      ...
      MessageDialog messageBox =
        new MessageDialog("All files are shared successfully",
        "Bluetooth DemoApp");
      messageBox.Commands.Add(new UICommand("OK", (uiCommand) =>
      {
        this.Frame.Navigate(typeof(MainPage));
      }));
      await messageBox.ShowAsync();
    }
    else
    {
      obexService = ObexService.GetDefaultForBluetoothDevice(BtDevice);
      obexService.Aborted += obexService_Aborted;
      obexService.ConnectionFailed += obexService_ConnectionFailed;
      obexService.DataTransferFailed += obexService_DataTransferFailed;
      obexService.DataTransferProgressed += 
        obexService_DataTransferProgressed;
      obexService.DataTransferSucceeded += 
        obexService_DataTransferSucceeded;
      obexService.DeviceConnected += obexService_DeviceConnected;
      obexService.Disconnected += obexService_Disconnected;
      obexService.Disconnecting += obexService_Disconnecting;
      obexService.ServiceConnected += obexService_ServiceConnected;
      await obexService.ConnectAsync();
    }
  });
}

當斷開連接的事件引發時,移除所有的處理常式,並清空 ObexService 實例。在資料傳輸過程中條件可能會出現要求您要中止當前的傳送。若要終止當前的傳輸,請調用 AbortAsync。用下面的代碼引發該中止事件,然後結束了與目標設備的連接:

async void obexService_Aborted(object sender, EventArgs e)
{
  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  {
    System.Diagnostics.Debug.WriteLine("Aborted");
    if (!filesToShare.Count.Equals(0))
    {
      filesToShare.RemoveAt(0);
    }
  });
}

總結

演示應用程式現已完成。通用程式的概念真的可以説明你在寫一塊單一的代碼為多個 Windows 平臺和形式因素,從而降低總體的發展努力。

這些圖書館中大量的 Windows 應用商店和 Windows Phone 應用程式已經使用搜索代碼創建 (免費的 Windows Phone App) 或 OBEX (通用應用程式),一睹這些 Api 是如何與應用程式一起工作。這些庫,可從 NuGet 存儲庫下載。只是搜索"BluetoothOBEX 應用程式商店"NuGet 線上對話方塊,直接從Visual Studio解決方案上,並作為對專案的引用導入這些庫。


Uday Gupta 是在交響樂 Teleca 公司的高級工程師產品開發 私人股份有限公司 在印度。他有經驗,在許多的.NET 技術,尤其是Windows Presentation Foundation、 Silverlight、 Windows Phone 和 Windows 8.x 版。

感謝以下的微軟技術專家對本文的審閱:Jeff凱利和 Guruprasad Subbarayan