Condividi tramite


Il presente articolo è stato tradotto automaticamente.

App universali

Arricchisci le tue app con OBEX

Uday Gupta

Scaricare il codice di esempio

Durante l'ultimo decennio, il Bluetooth è diventata una tecnologia ampiamente utilizzata per la comunicazione wireless a corto raggio tra dispositivi quali telefoni cellulari, personal computer e cuffie. Il Bluetooth Special Interest Group (BTSIG) è l'organismo di settore che definisce le norme per i servizi wireless nelle specifiche del profilo Bluetooth .

Un tale profilo è l'oggetto spingere il profilo (OPP), che viene utilizzato per inviare i file da una periferica a altra. L'oggetto Exchange Protocol (OBEX) fa parte della Fondazione dell'avv. OBEX è utilizzato anche in profili diversi da OPP, in quanto è un protocollo generico per trasferire oggetti tra dispositivi.

Per gli sviluppatori che desiderano per utilizzare OBEX loro apps, ho sviluppato un set di API sopra il Windows Runtime (WinRT) Bluetooth API che forniscono OBEX all'interno della app. Queste API vengono come un pacchetto di libreria per applicazioni universali, che significa App Store di Windows e Windows Phone Silverlight App può sfruttare lo stesso set di API.

OBEX e OPP

In primo luogo, è importante capire quali OBEX e OPP sono e come funzionano. OPP consente a un dispositivo Bluetooth invia un file o un oggetto a un altro dispositivo in grado di supportare OPP Bluetooth . La destinazione d'uso per OBEX era condivisione di file via canali infrarossi. La BTSIG ha scelto di riutilizzare questo protocollo per la condivisione tramite Bluetooth. A parte il mezzo di trasporto sottostante OBEX-oltre all'infrarosso e OBEX-sovra -Bluetooth sono simili.

OBEX è basato su un modello client-server in cui il destinatario dispositivo Bluetooth è in esecuzione un server OBEX che ascolta e accetta connessioni client. Il dispositivo Bluetooth client si connette al dispositivo Bluetooth server come un canale di flusso tramite Bluetooth. I requisiti di autenticazione per consentire la connessione e il trasferimento di oggetti dipendono dal servizio o applicazione utilizzando OBEX. Ad esempio, OPP può consentire una connessione non autenticata al fine di snellire il processo di rapidamente lo scambio di biglietti da visita. Altri servizi utilizzando OBEX possono solo consentire connessioni autenticate.

I file sono condivisi utilizzando tre tipi di pacchetti. Questi pacchetti sono conosciuti come primo PUT, intermedio messo e ultima mettere. Il primo pacchetto PUT segna l'inizializzazione di trasferimento file e l'ultimo pacchetto PUT segna il suo completamento. I più intermedi PUT pacchetti contengono la maggior parte dei dati. Dopo che il server riceve ogni pacchetto PUT, restituisce un pacchetto di riconoscimento per il client.

In uno scenario tipico, OBEX pacchetti vengono inviati come segue:

  1. Il client OBEX si connette al dispositivo destinatario inviando un pacchetto di connessione. Questo pacchetto consente di specificare che la dimensione massima pacchetto client può ricevere.
  2. Dopo aver ricevuto una risposta dal server che indica la connessione è stata accettata, il client OBEX invia il primo pacchetto PUT. Questo file contiene i metadati che descrivono l'oggetto, compreso il nome del file e la dimensione. (Mentre il protocollo OBEX permette di questo primo pacchetto messo ad includere anche i dati dell'oggetto, l'implementazione di OBEX della libreria che ho sviluppato non invia uno qualsiasi di tali dati nel primo pacchetto PUT.)
  3. Dopo la conferma di ricezione del server ha il primo pacchetto PUT, il client OBEX invia i PUT più pacchetti che contengono i dati dell'oggetto. La lunghezza di questi pacchetti è limitata dalla dimensione massima del pacchetto che può ricevere il server, impostare la risposta del server per collegare pacchetto inviato in passo uno.
  4. L'ultimo pacchetto PUT contiene l'ultimo messo costante e il blocco finale di dati oggetto.
  5. Terminata la condivisione di file, il client OBEX invia un pacchetto di disconnessione e chiude la connessione Bluetooth . Il protocollo OBEX permette la ripetizione di passaggi da due a tre per inviare più oggetti nella stessa connessione.

In qualsiasi punto, il client OBEX può interrompere il processo di condivisione inviando un pacchetto ABORT. La condivisione è immediatamente annullata. La libreria che ho scritto, sono nascosti i dettagli di implementazione del protocollo OBEX e vedrai solo API ad alto livello.

La libreria OBEX

Libreria client Bluetooth OBEX per applicazioni Windows Store è stata progettata come una libreria portabile di targeting: App Store di Windows e Windows Phone applicazioni Silverlight 8.1. Esso contiene tre dll che rendono la biblioteca un runtime client OBEX. Ogni DLL è progettato per gestire un compito specifico: Bluetooth.Core.Service, Bluetooth.Core.Sockets e Bluetooth.Services.Obex.

Bluetooth Servizio di base il file Bluetooth.Core.Service.dll contiene il Bluetooth.Spazio dei nomi Core.Service. Questa libreria è progettata per la ricerca e conteggio di dispositivi Bluetooth nelle vicinanze accoppiati con il dispositivo client (vedere Figura 1). Attualmente, si è limitato a un sola volta conte di dispositivi accoppiati. Le versioni future conterrà un osservatore a continuare a cercare altri dispositivi Bluetooth .

Figura 1 metodi ed eventi associati da BluetoothService

Metodo (parametri) Eventi associati
[statico] GetDefault Nessun evento associato
SearchForPairedDevicesAsync

Successo - SearchForDevicesSucceeded

Fallimento - SearchForPairedDevicesFailed

Il nucleo di servizio Bluetooth è rappresentato da una classe statica chiamata BluetoothService, mostrato Figura 2. Questa classe ha un'API per contare in modo asincrono dispositivi.

Figura 2 BluetoothService contando abbinato a dispositivi

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 Core socket il file Bluetooth.Core.Sockets.dll contiene il Bluetooth.Spazio dei nomi Core.Sockets ed è progettato per supportare le operazioni socket basati sul flusso tramite una connessione Bluetooth . La funzionalità di presa viene esposto tramite la classe BluetoothSockets (vedere Figura 3). Questa è presa nessun TCP o UDP. Tutte le comunicazioni con il dispositivo destinatario avviene attraverso BluetoothSockets.

Figura 3 metodi ed eventi associati da BluetoothSockets

Metodo (parametri) Eventi associati

Costruttore (Bluetooth.Core.Services.BluetoothDevice)

Costruttore (Bluetooth.Core.Services.BluetoothDevice, UInt32)

Costruttore (Bluetooth.Core.Services.BluetoothDevice, System. String)

Costruttore (Bluetooth.Core.Services.BluetoothDevice, UInt32, System. String)

Nessun evento associato
PrepareSocketAsync

Successo – SocketConnected

Fallimento – ErrorOccured

SendDataAsync(System.Byte[])

SendDataAsync(System.String)

Nessun evento associato
CloseSocket SocketClosed
Nessun metodo associato DataReceived

Bluetooth Servizi Obex Bluetooth.Il file Services.Obex.dll contiene il Bluetooth.Spazio dei nomi Services.Obex. Questa è l'implementazione di base di OBEX, esposto tramite una classe denominata ObexService. Questa classe fornisce la visualizzazione sottratto delle specifiche Bluetooth OPP. Espone il metodo che aiuta a connettersi, inviare e staccare il dispositivo Bluetooth del destinatario. Figura 4 elenca le API e gli eventi associati a questa classe espone, e Figura 5 viene illustrato l'utilizzo.

Figura 4 metodi ed eventi associati da ObexService

Metodo (parametri) Eventi associati
[statico] GetDefaultForBluetoothDevice (Bluetooth.Core.Services.BluetoothDevice) Nessun evento associato
ConnectAsync

Successo – uetooth

Fallimento – ConnectionFailed

SendFileAsync(Windows.Storage.IStorageFile)

Successo:

ServiceConnected

DataTransferProgressed

DataTransferSucceeded

Scollegamento

Disconnessi

Guasto:

ConnectionFailed

DataTransferFailed

AbortAsync Interrotto

Figura 5 utilizzo servizio 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
}

Uno scenario tipico di utilizzo per l'utilizzo di queste librerie è qualcosa di simile:

  • Utilizzando le API in blu -­dente.Core.Service, contare tutti i dispositivi accoppiati OPP abilitati Bluetooth . Controllo OPP-capacità è già implementato.
  • Ottenere l'istanza di BluetoothDevice con cui si desidera condividere i file.
  • Ottenere un'istanza di ObexService per il destinatario del dispositivo Bluetooth passando l'istanza di BluetoothDevice al metodo factory. La classe ObexService internamente creerà un'istanza di BluetoothSocket, sopra cui il ObexService condividere il file.
  • Terminata la condivisione di file, il ObexService è disconnesso automaticamente.

Per iniziare

Perché la mia biblioteca è mirata verso applicazioni Windows Store e applicazioni Windows Phone 8.1, inizierò con una app universale. Queste sono un ottimo modo di sviluppare applicazioni per tutte le periferiche di Windows. Per ulteriori informazioni su universal apps, visita bit.ly/1h3AQeu. Per iniziare con applicazioni universali, io uso Visual Studio 2013 e creare un nuovo progetto di universal apps nel nodo App Store (Vedi Figura 6). Ho usato Visual c#, ma è anche possibile utilizzare Visual Basic e Visual C++.

App universale vuota per creare un nuovo progetto
Figura 6 App universale vuota per creare un nuovo progetto

Prima di iniziare la programmazione per un app di client Bluetooth OBEX, aggiornerò il package.appx­file manifesto per entrambi i progetti (applicazioni per Windows 8.1 e 8.1 di Windows Phone):

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

Per applicare questo aggiornamento, apro package.appx­­manifesto come un file di codice scegliendo Visualizza codice nel menu di scelta rapida in Esplora soluzioni. Ti metto questo frammento dove Tag termina. Tale frammento di codice è necessaria per fornire funzionalità dispositivo-livello di utilizzare il servizio di comunicazione (RFCOMM) frequenza radio Bluetooth con questa app. Specificato anche tutti i servizi e i tipi di dispositivi compatibili con questo dispositivo.

Per il mio scenario, ho bisogno di supporto obexObjectPush dal dispositivo compatibile con qualsiasi dispositivo abilitato per OPP. Per ulteriori informazioni sui profili supportati su Windows 8.1 e 8.1 di Windows Phone, visitare bit.ly/1pG6rYO. Se tale funzionalità non è menzionato, enumerazione dispositivo riuscirà con CapabilityNotDefined enum costante.

Prima di iniziare la codifica, aggiungerò il riferimento ai tre Biblioteca file citato in precedenza così posso usare l'implementazione OBEX all'interno di tali librerie. Ho bisogno di un riferimento aggiuntivo per queste librerie per entrambi i progetti separatamente. Se non è stato aggiunto il riferimento, il progetto non sarà in grado di utilizzare tutte le caratteristiche.

Io ti seguirò questi modelli di codificazione e pratiche:

  • Implementare la progettazione UX per app Windows Store 8.1 nel progetto Windows.
  • Attuare UX design per le applicazioni Windows Phone 8.1 nel progetto Windows Phone.
  • Implementare la caratteristica comune nel progetto Shared.
  • Eseguire specifici della piattaforma implementazione nel progetto Shared utilizzando costanti del compilatore specifico della piattaforma. Per 8.1 di Windows, io uso WINDOWS_APP. Per Windows Phone 8.1, io uso WINDOWS_PHONE_APP. Costanti del compilatore sono già definite come parte del progetto.

Scarica il codice di esempio per ottenere esperienza pratica con queste librerie, insieme con le pratiche di codificante che deve seguire per lo sviluppo di applicazioni universali. Figura 7 Mostra finestra di Esplora il campione del progetto con la struttura di file e modelli.

Esplora dell'App BluetoothDemo
Figura 7 Esplora dell'App BluetoothDemo

L'enumerazione abbinato a dispositivi

Prima che posso condividere i file con un dispositivo abbinato, ho bisogno di vedere l'elenco dei dispositivi associati e selezionare una destinazione. Otterrò la maniglia all'istanza di Bluetooth.Core.Services.BluetoothService, che rappresenta il nucleo servizio Bluetooth fornito dal mio dispositivo. Acquistare questa istanza utilizzando il metodo statico fabbrica GetDefault, perché c'è un solo servizio Bluetooth disponibile per ogni dispositivo.

Per l'enumerazione, farò una chiamata al metodo SearchForPairedDevicesAsync. Questo metodo inizia l'enumerazione dei dispositivi accoppiati con il mio dispositivo. Per le app di Windows Store 8.1, è necessario consentire l'utilizzo di un dispositivo abbinato per ottenere i dispositivi enumerati. Se a bloccare l'uso, non enumerato quel dispositivo abbinato.

Se tale API ha esito positivo, essa genera l'evento SearchForPairedDevicesSucceeded e recuperare l'insieme dei dispositivi associati dal relativo argomento di evento. In caso contrario, l'evento SearchForPairedDevicesFailed verrà generato, con costante di fallimento enum disponibile nel suo argomento dell'evento. Figura 8 illustrato il codice per l'enumerazione dei dispositivi.

Figura 8 l'enumerazione abbinato a dispositivi

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();
}

Ho anche fornito il pulsante scansione in BottomAppBar di 8.1 per Windows e ApplicationBar per Windows Phone 8.1. In questo modo un utente app può ripetere la scansione per dispositivi quando è arrivato un nuovo dispositivo abbinato.

Durante l'enumerazione delle periferiche su Windows Phone 8.1, esso enumera tutti i dispositivi compatibili OBEX, indipendentemente dalla loro presenza fisica e se la radio Bluetooth sia acceso. Tuttavia, durante l'enumerazione delle periferiche su Windows 8.1, elencherà solo quei dispositivi presenti fisicamente vicino al dispositivo Windows 8.1 e con loro radio Bluetooth acceso.

Una volta io enumerare i dispositivi accoppiati, posso selezionare un dispositivo per condividere i file. Ogni dispositivo è rappresentato come un oggetto del Bluetooth.Classe di Core.Services.BluetoothDevice. L'oggetto contiene dettagli di connessione e il nome visualizzato del dispositivo accoppiato. Il Bluetooth.Services.Obex.ObexService utilizzerà i dettagli della connessione internamente per creare un'istanza di Bluetooth.Core.Sock­ets.BluetoothSocket e collegare il dispositivo abbinato.

Utilizzando ObexService

Una volta che ottengo l'istanza del Bluetooth.Oggetto Core.Services.BluetoothDevice che rappresenta il mio dispositivo mirato per la condivisione di file, posso utilizzare Bluetooth.Services.Obex.ObexService per la condivisione di file tramite OPP. Ho bisogno anche l'elenco dei file così posso accodare li per la condivisione. Nell'esempio di codice, ho fornito solo una manciata di file. In caso contrario, potrei usare Windows.Storage.Pickers.FileOpenPicker (vedere bit.ly/1qtiLeh) o logica personalizzata dal mio LocalFolder (vedere bit.ly/1qtiSGI) per selezionare più file.

A partire da ora, posso solo condividere un file per ogni connessione. Quando condivisione è completo, viene chiusa la connessione al dispositivo di destinazione. Se ho bisogno di inviare più file, è necessario ottenere l'handle Blue­dente.Istanza di Services.Obex.ObexService più volte. Io posso acquisire questa istanza utilizzando il metodo statico fabbrica GetDefaultForBluetoothDevice (Bluetooth.Core.Services.BluetoothDevice). Questo metodo restituisce la singola istanza di Bluetooth.Services.Obex.ObexService che rappresenta il servizio Obex sul dispositivo.

Per rappresentare il file da condividere, si utilizzerà la classe FileItemToShare. Questo file contiene il nome, il percorso e la dimensione del file e l'istanza di Windows.Storage.IStorageFile (vedere bit.ly/1qMcZlB) che rappresenta l'istanza del file sul disco. Io sarò in coda tutti i file che devo condividere in termini di oggetti di struttura dati. Quando la condivisione di file multipli, il primo file dell'elenco è quella attualmente condivisa. Esso viene rimosso dall'elenco quando condivisione è completa. Figura 9 illustrato come collegare il ObexService ed i suoi eventi per la condivisione di file.

Figura 9 aggancio ObexService ed i suoi eventi

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();
}

Quando chiamo il metodo ConnectAsync, l'oggetto ObexService ottiene le proprietà di connessione dall'oggetto BluetoothDevice, che era passata nel metodo factory. Tenta di creare una connessione con il BluetoothDevice mirate sul canale Bluetooth . Quando è successo, genera l'evento uetooth. Figura 10 viene illustrato il gestore eventi uetooth di ObexService.

Metodo del gestore di eventi uetooth figura 10

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);
    }
    ...
  });
}

Non appena il dispositivo è collegato al dispositivo di destinazione, inizierò condivisione del file indice 0 dall'elenco dei file. Il file è condiviso chiamando SendFileAsync(Windows.Storage.IStorageFile) e passando l'oggetto file rappresentato da IStorageFile da un oggetto di tipo struttura dati FileToShare. Quando questo metodo viene chiamato, il ObexService tenta di connettersi al Server OBEX in esecuzione nel dispositivo di destinazione. Se la connessione ha esito positivo, esso genererà l'evento ServiceConnected. In caso contrario, esso genererà ConnectionFailed evento. Questo codice viene illustrato il gestore eventi 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;
  });
}

Figura 11 viene illustrato il gestore eventi ConnectionFailed di ObexService.

Figura 11 metodo del gestore eventi 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);
  });
}

Quando il mio dispositivo si connette al server OBEX del dispositivo mirato, inizia il processo di condivisione di file. Il progresso del file condiviso può essere determinato dall'evento DataTransferProgressed. Il codice riportato di seguito viene illustrato il metodo 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;
  });
}

Terminata la condivisione di file, che genera il DataTransfer­evento Succeeded. Se il file sharing è infruttuoso, genera il DataTransferFailedEvent. Il codice seguente mostra DataTransfer­Succeeded gestore eventi:

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

In caso di un errore di condivisione di file, verrà generato un evento DataTransferFailed. Nel codice seguente viene illustrato il gestore eventi:

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);
  });
}

Quando il trasferimento dei dati è finito, il file condiviso viene rimosso dall'elenco e il ObexService è scollegato. Quando si scollega il ObexService, genera l'evento di disconnessione. E, quando la connessione è scollegata correttamente, viene generato l'evento disconnessa. Il gestore di evento di disconnessione è illustrato di seguito:

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

Una volta che la connessione è disconnesso correttamente, il codice in Figura 12 maniglie generando l'evento disconnessa.

Figura 12 scollegato il metodo del gestore eventi

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();
    }
  });
}

Quando viene generato l'evento disconnesso, rimuovere tutti i gestori e cancellare l'istanza ObexService. Durante il trasferimento dei dati, possono insorgere condizioni che richiedono di interrompere il trasferimento di corrente. Per annullare un trasferimento di corrente, chiamare AbortAsync. Con il codice riportato di seguito viene generato l'evento di Aborted e poi è finito il collegamento al dispositivo di destinazione:

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);
    }
  });
}

Conclusioni

L'applicazione demo è ora completa. Il concetto di universal apps può davvero aiutare nella scrittura di un singolo pezzo di codice per più piattaforme Windows e fattori di forma, riducendo così lo sforzo di sviluppo globale.

Ho usato queste librerie in un numero di App Store di Windows e Windows Phone. Ricerca per codice creare (un App gratuita Windows Phone) o OBEX (Universal App) e avere un assaggio di come queste API funzionano in congiunzione con l'app. Queste librerie sono disponibili da scaricare dal repository NuGet. Basta cercare "Bluetooth OBEX per Store Apps" NuGet online nella finestra di dialogo, retta dalla soluzione Visual Studio e importare queste librerie come riferimento ai progetti.


Uday Gupta è uno sviluppo di prodotto-ingegnere senior presso Symphony Teleca Corp. Pvt Ltd in India. Ha esperienza in molte tecnologie .NET, soprattutto Windows Presentation Foundation, Silverlight, Windows Phone e Windows 8. x.

Grazie ai seguenti esperti tecnici Microsoft per la revisione di questo articolo: Jeff Kelley e Laura Piervincenzo