Partager via


Cet article a fait l'objet d'une traduction automatique.

Applications universelles

Dotez vos applications d'OBEX

Uday Gupta

Télécharger l'exemple de code

Au cours de la dernière décennie, le Bluetooth est devenu une technologie largement utilisée pour les communications sans fil à courte portée entre appareils tels que téléphones mobiles, ordinateurs personnels et le casque. Le groupe d'intérêt spécial Bluetooth (BTSIG) est l'organisme de l'industrie qui définit les normes pour les services sans fil dans les spécifications de profil Bluetooth .

Un tel profil est l'Object Push profil (OPP), qui sert à envoyer des fichiers d'un périphérique à un autre. Le Protocole OBEX (Object Exchange) appartient à la Fondation de la police provinciale. OBEX est également utilisé dans les profils d'autres OPP, car c'est un protocole générique pour transférer des objets entre les périphériques.

Pour les développeurs qui cherchent à utiliser OBEX au sein de leurs applications, j'ai développé un ensemble d'API sur le Windows Runtime (WinRT) Bluetooth API qui fournissent OBEX de l'app. Ces API est comme un paquet de bibliothèque pour des applications universelles, qui signifie Windows Store apps et les applications Windows Phone Silverlight peut exploiter le même ensemble d'API.

OBEX et OPP

Tout d'abord, il est important de comprendre ce que OBEX et OPP sont et comment ils fonctionnent. OPP permet à un périphérique Bluetooth envoyer un fichier ou un objet à un autre appareil OPP compatible Bluetooth . L'utilisation prévue pour OBEX est fichier partager via les canaux infrarouges. Le BTSIG a choisi de réutiliser ce protocole pour fichier partage via Bluetooth. Mis à part le milieu de transport sous-jacent, OBEX-over-infrarouge et OBEX-over -Bluetooth sont similaires.

OBEX est basé sur un modèle client-serveur dans lequel le bénéficiaire périphérique Bluetooth s'exécute un serveur OBEX qui écoute et accepte les connexions clientes. Le périphérique Bluetooth de client se connecte au périphérique Bluetooth serveur comme un canal de flux de données via Bluetooth. Les exigences d'authentification pour permettre la connexion et le transfert d'objets dépendent le service ou l'application à l'aide de OBEX. Par exemple, les OPP peut permettre une connexion non authentifiée afin de rationaliser le processus d'échange rapidement des cartes de visite. Autres services à l'aide de OBEX peuvent autoriser uniquement les connexions authentifiées.

Les fichiers sont partagés à l'aide de trois types de paquets. Ces paquets sont connus comme premier PUT, intermédiaire mis et dernier mettre. Le premier paquet PUT marque l'initialisation de transfert de fichier et le dernier paquet PUT marque son achèvement. Les multiples paquets intermédiaires de PUT contenant la majeure partie des données. Lorsque le serveur reçoit chaque paquet PUT, il retourne un paquet d'accusé de réception au client.

Dans un scénario typique, les paquets OBEX sont envoyés comme suit :

  1. Le client OBEX se connecte au périphérique destinataire en envoyant un paquet connect. Ce paquet spécifie que la taille maximale du paquet, le client peut recevoir.
  2. Après avoir reçu une réponse du serveur indiquant la connexion a été acceptée, le client OBEX envoie le premier paquet PUT. Celui-ci contient les métadonnées décrivant l'objet, y compris le nom du fichier et la taille. (Alors que le Protocole OBEX permet pour ce premier paquet PUT d'inclure également les données de l'objet, la mise en œuvre de l'OBEX dans la bibliothèque, que j'ai développé n'envoie aucune de ces données dans le premier paquet PUT.)
  3. Après que l'accusé de réception du serveur a le premier paquet PUT, le client OBEX envoie les paquets PUT multiples qui contiennent des données de l'objet. La longueur de ces paquets est limitée par la taille de paquet maximale que du serveur peut recevoir, par la réponse du serveur au paquet connect envoyé dans la première étape.
  4. Le dernier paquet PUT contient le dernier mettre constant et le dernier segment de données de l'objet.
  5. Une fois que le partage de fichiers est terminé, le client OBEX envoie un paquet de déconnexion et ferme la connexion Bluetooth . Le Protocole OBEX permet la répétition des étapes deux à trois pour envoyer plusieurs objets sur la même connexion.

À tout moment, le client OBEX peut interrompre le processus de partage en envoyant un paquet d'ABORT. Le partage est immédiatement annulé. Dans la bibliothèque que j'ai écrit, les détails d'implémentation de Protocole OBEX sont cachés et vous ne verrez que des API de haut niveau.

La bibliothèque de l'OBEX

La bibliothèque de client OBEX de Bluetooth pour Windows Store apps est conçue comme une bibliothèque portable de ciblage : Apps Store de Windows et Windows Phone applications Silverlight 8.1. Il contient trois dll qui rendent à la bibliothèque un runtime pour le client OBEX. Chaque DLL est conçue pour gérer une tâche précise : Bluetooth.Core.Service, Bluetooth.Core.Sockets et Bluetooth.Services.Obex.

Bluetooth Service de base le fichier Bluetooth.Core.Service.dll contient le Bluetooth.Espace de noms Core.Service. Cette bibliothèque est conçue pour rechercher et comte, à proximité des appareils Bluetooth jumelés avec la machine cliente (voir Figure 1). Actuellement, il est limité à un compte unique des appareils couplés. Les versions futures contiendra un veilleur à continuer à chercher d'autres appareils Bluetooth .

Figure 1 les méthodes et les événements associés à partir de BluetoothService

Méthode (avec paramètres) Événements associés
[statique] GetDefault Aucun événement associé
SearchForPairedDevicesAsync

Succès - SearchForDevicesSucceeded

Échec - SearchForPairedDevicesFailed

Le noyau de la fonction Bluetooth est représenté par une classe statique appelée BluetoothService, montré dans Figure 2. Cette classe possède une API asynchrone compter périphériques.

La figure 2 BluetoothService comptage Appareils jumelés

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 Sockets de base le fichier Bluetooth.Core.Sockets.dll contient le Bluetooth.Espace de noms Core.Sockets et vise à soutenir des opérations de prise de fonction de flux via une connexion Bluetooth . La fonctionnalité de prise est exposée via la classe BluetoothSockets (voir Figure 3). Il s'agit d'un socket UDP ni un TCP. Toutes les communications avec l'appareil destinataire s'effectue par BluetoothSockets.

Figure 3 méthodes et événements associés de BluetoothSockets

Méthode (avec paramètres) Événements associés

Constructeur (Bluetooth.Core.Services.BluetoothDevice)

Constructeur (Bluetooth.Core.Services.BluetoothDevice, System.UInt32)

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

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

Aucun événement associé
PrepareSocketAsync

Succès – SocketConnected

Échec – ErrorOccured

SendDataAsync(System.Byte[])

SendDataAsync(System.String)

Aucun événement associé
CloseSocket SocketClosed
Aucune méthode associée DataReceived

Bluetooth Services Obex le Bluetooth.Fichier Services.Obex.dll contient le Bluetooth.Espace de noms Services.Obex. Il s'agit de l'application de base de l'OBEX, exposé dans une classe nommée ObexService. Cette classe fournit la vue abstraite des spécifications Bluetooth OPP. Il expose la méthode qui permet de connecter, d'envoyer et de débrancher le destinataire périphérique Bluetooth . Figure 4 répertorie les API et les événements associés, cette classe expose, et Figure 5 illustre l'utilisation.

Figure 4 méthodes et événements associés de ObexService

Méthode (avec paramètres) Événements associés
[statique] GetDefaultForBluetoothDevice (Bluetooth.Core.Services.BluetoothDevice) Aucun événement associé
ConnectAsync

Succès – DeviceConnected

Échec – ConnectionFailed

SendFileAsync(Windows.Storage.IStorageFile)

Opération réussie :

ServiceConnected

DataTransferProgressed

DataTransferSucceeded

Déconnexion

Déconnecté

Échec :

ConnectionFailed

DataTransferFailed

AbortAsync Abandonné

Figure 5 utilisation de Service 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
}

Un scénario d'utilisation typique pour l'utilisation de ces bibliothèques est quelque chose comme ceci :

  • Aide des API de Blue -­dent.Core.Service, compter tous les dispositifs OPP compatible Bluetooth appariés. Vérification de l'OPP-capacité est déjà implémentée.
  • Obtenir l'instance de BluetoothDevice avec qui vous voulez partager des fichiers.
  • Obtenez une instance de ObexService pour le destinataire périphérique Bluetooth en passant l'instance de BluetoothDevice à la méthode de fabrique. La classe ObexService crée en interne une instance de BluetoothSocket, sur lequel le ObexService se partageront le fichier.
  • Une fois que le partage de fichiers est terminé, le ObexService est déconnecté automatiquement.

Pour commencer

Parce que ma bibliothèque est ciblée vers Windows Store apps et applications Windows Phone 8.1, je vais commencer par une application universelle. Voici un excellent moyen de développer des applications pour tous les périphériques de Windows. Pour en savoir plus sur les applications universelles, visitez bit.ly/1h3AQeu. Pour commencer avec des applications universelles, je vais utiliser Visual Studio 2013 et créez un projet sous le nœud de l'Apps Store apps universelles (voir Figure 6). J'ai utilisé Visual c#, mais vous pouvez également utiliser Visual Basic et Visual C++.

vierge App universelle pour créer un nouveau projet
Figure 6 vierge App universelle pour créer un nouveau projet

Avant de commencer la programmation pour une application cliente de Bluetooth OBEX, je vais mettre à jour le package.appx­fichier de manifeste pour les deux projets (applications pour Windows 8.1 et Windows Phone 8.1) :

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

Pour appliquer cette mise à jour, j'ouvre package.appx­­manifeste comme un fichier de code en choisissant Afficher le Code dans le menu contextuel dans l'Explorateur de solutions. Je vais placer cet extrait où extrémités de la balise. Cet extrait de code est tenu de fournir la capacité au niveau du périphérique à utiliser le service de communication (RFCOMM) de fréquence radio Bluetooth avec ce soft. J'ai précisé également tous les services et les types d'appareils compatibles avec cet appareil.

Pour mon scénario, j'ai besoin d'aide obexObjectPush de l'appareil qui est compatible avec n'importe quel périphérique compatible OPP. Pour plus d'informations sur les profils pris en charge sur Windows 8.1 et 8.1 de Windows Phone, visitez bit.ly/1pG6rYO. Si cette fonctionnalité n'est pas mentionnée, l'énumération va échouer avec CapabilityNotDefined enum constante.

Avant que je commencer à coder, je vais ajouter la référence aux trois bibliothèque fichiers mentionnés plus tôt, donc je peux utiliser la mise en œuvre de l'OBEX au sein de ces bibliothèques. J'ai besoin d'une référence d'ajouter à ces bibliothèques pour les deux projets séparément. Si la référence n'est pas ajoutée, le projet ne sera pas en mesure d'utiliser toutes les fonctionnalités.

Je vais suivre ces modèles de codage et les pratiques :

  • Mettre en œuvre la conception UX pour Windows Store 8.1 app dans projet Windows.
  • Implémenter la conception UX pour les applications Windows Phone 8.1 projet Windows Phone.
  • Implémenter une fonctionnalité commune au projet partagé.
  • Effectuer spécifique à la plateforme mise en œuvre dans le projet partagé à l'aide de constantes de compilation spécifiques à la plateforme. Pour 8.1 de Windows, je vais utiliser WINDOWS_APP. Pour Windows Phone 8.1, je vais utiliser WINDOWS_PHONE_APP. Ces constantes de compilation sont déjà définis dans le cadre du projet.

Téléchargez l'exemple de code pour obtenir une expérience pratique avec ces bibliothèques, ainsi que les pratiques de codage, vous devez suivre pour développer des applications universelles. La figure 7 montre la fenêtre Explorateur de solutions de l'exemple de projet avec la structure de fichiers et de motifs.

l'Explorateur de solutions de BluetoothDemo App
Figure 7 l'Explorateur de solutions de BluetoothDemo App

Énumération des appareils jumelés

Avant que je peux partager des fichiers avec un appareil associé, j'ai besoin de voir la liste des appareils couplés et sélectionnez une cible. Je vais obtenir le handle de l'instance de Bluetooth.Core.Services.BluetoothService, qui représente le noyau de la fonction Bluetooth fournie par mon appareil. J'acquiers cette instance à l'aide de la méthode de fabrique statique GetDefault, parce qu'il n'y a qu'un seul service Bluetooth disponible par appareil.

Pour l'énumération, je vais faire un appel à la méthode SearchForPairedDevicesAsync. Cette méthode va commencer l'énumération des périphériques jumelés avec mon appareil. Pour les applications Windows Store 8.1, j'ai besoin d'autoriser l'utilisation d'un appareil jumelé pour obtenir les dispositifs énumérés. Si je bloque l'utilisation, cet appareil ne sera pas énuméré.

Si cette API réussit, il déclenche l'événement SearchForPairedDevicesSucceeded et récupérer de la collection des appareils associés depuis son argument d'événement. Dans le cas contraire, l'événement SearchForPairedDevicesFailed est déclenché, avec constante d'enum failure disponible dans son argument d'événement. Figure 8 affiche le code pour l'énumération des périphériques.

Figure 8 énumérant les appareils jumelés

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

J'ai également fourni le bouton scan dans BottomAppBar pour Windows 8.1 et ApplicationBar pour Windows Phone 8.1. De cette façon un utilisateur app peut rescan pour appareils lorsqu'un appareil jumelé nouveau est arrivé.

Lors de l'énumération des périphériques sur Windows Phone 8.1, énumère tous les périphériques prenant en charge OBEX, indépendamment de leur présence physique et la question de savoir si la radio Bluetooth est allumée. Toutefois, lors de l'énumération des périphériques sur Windows 8.1, il listera uniquement ces dispositifs physiquement présents à proximité de l'appareil 8.1 de Windows et avec leur radio Bluetooth allumé.

Une fois que j'énumère les périphériques appariés, je peux choisir un dispositif de partager des fichiers. Chaque périphérique est représenté comme un objet du Bluetooth.Core.Services.BluetoothDevice classe. L'objet contient les détails de connexion et le nom complet de l'appareil appairé. Le Bluetooth.Services.Obex.ObexService utilisera les coordonnées de connexion en interne pour créer une instance de la Bluetooth.Core.Sock­ets.BluetoothSocket et connectez-vous à l'appareil appairé.

À l'aide de ObexService

Une fois que je reçois de l'instance du Bluetooth.Objet Core.Services.BluetoothDevice qui représente mon périphérique cible pour le partage de fichiers, je peux utiliser Bluetooth.Services.Obex.ObexService pour le partage de fichiers à l'aide de la police provinciale. J'ai aussi besoin de la liste des fichiers donc je peux leur file d'attente pour le partage. Dans l'exemple de code, j'ai seulement fourni une poignée de fichiers. Sinon, je pourrais utiliser Windows.Storage.Pickers.FileOpenPicker (voir bit.ly/1qtiLeh) ou une logique personnalisée de mon Windows.Storage.ApplicationData.Current.LocalFolder (voir bit.ly/1qtiSGI) pour sélectionner plusieurs fichiers.

A partir de maintenant, je ne peux que partager un fichier par connexion. Lorsque le partage est terminée, la connexion pour le périphérique cible est fermée. Si j'ai besoin d'envoyer plusieurs fichiers, j'ai besoin pour obtenir le handle de bleu­dent.Services.Obex.ObexService instance plusieurs fois. Je peux acquérir cette instance à l'aide de la méthode de fabrique statique GetDefaultForBluetoothDevice (Bluetooth.Core.Services.BluetoothDevice). Cette méthode retourne l'instance unique de la Bluetooth.Services.Obex.ObexService qui représente le service Obex sur le périphérique.

Pour représenter le dossier à partager, je vais utiliser la classe FileItemToShare. Celui-ci contient le nom, le chemin d'accès et la taille du fichier et l'instance de Windows.Storage.IStorageFile (voir bit.ly/1qMcZlB) qui représente l'instance du fichier sur le disque. Je vais en file d'attente tous les fichiers que je dois partager en ce qui concerne les objets de structure de données. Lors du partage de fichiers multiples, le premier fichier de la liste est celui actuellement partagée. Il est supprimé de la liste lorsque le partage est terminé. Figure 9 montre comment raccorder une ObexService et de ses événements de partage de fichiers.

Figure 9 accrochage ObexService et ses événements

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

Quand je l'appelle la méthode ConnectAsync, l'objet de ObexService obtient les propriétés de connexion de l'objet BluetoothDevice, qui a été adoptée dans la méthode de fabrique. Il tente de créer une connexion avec la BluetoothDevice ciblée sur canal Bluetooth . Quand c'est réussi, il déclenche l'événement DeviceConnected. Figure 10 montre le gestionnaire d'événements DeviceConnected de ObexService.

Figure 10 méthode de gestionnaire d'événement 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);
    }
    ...
  });
}

Dès que le périphérique est connecté à l'appareil ciblé, je vais commencer à partager le fichier à l'index 0 de la liste des fichiers. Le fichier est partagé en appelant SendFileAsync(Windows.Storage.IStorageFile) et en passant l'objet fichier représenté par IStorageFile de l'objet de type FileToShare structure de données. Lorsque cette méthode est appelée, la ObexService tente de se connecter au serveur OBEX s'exécutant sur le périphérique cible. Si la connexion est réussie, elle déclenche l'événement ServiceConnected. Dans le cas contraire, il déclenche ConnectionFailed événement. Copiez le code suivant montre le gestionnaire d'événements 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;
  });
}

Figure 11 montre le gestionnaire d'événements ConnectionFailed de ObexService.

Figure 11 méthode de gestionnaire d'événement 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);
  });
}

Lorsque mon appareil se connecte au serveur OBEX de l'appareil ciblé, le processus de partage de fichiers commence. L'évolution des dossiers partagés peut être déterminée à partir de l'événement DataTransferProgressed. Le code suivant illustre la méthode 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;
  });
}

Une fois que le partage de fichiers est terminé, qui déclenche le DataTransfer­événement Succeeded. Si le partage de fichiers est infructueux, il déclenche le DataTransferFailedEvent. Le code suivant illustre DataTransfer­gestionnaire d'événements d'opération réussie :

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

Dans le cas d'une erreur de partage de fichiers, il déclenche un événement DataTransferFailed. Le gestionnaire d'événements est illustrée dans le code suivant :

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

Lorsque le transfert des données est terminé, le fichier partagé est supprimé de la liste et la ObexService est déconnecté. Lorsque le ObexService est débranché, il déclenche l'événement de déconnexion. Et, lorsque la connexion est déconnectée correctement, puis l'événement déconnectée est déclenché. Le gestionnaire d'événements de déconnexion est montré ici :

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

Une fois que la connexion est interrompue avec succès, le code dans Figure 12 poignées déclenchant l'événement déconnecté.

Figure 12 déconnecté de la méthode de gestionnaire d'événement

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

Lorsque l'événement déconnectée est déclenché, supprimer tous les gestionnaires et vider l'instance ObexService. Lors du transfert de données, des conditions peuvent survenir qui vous obligent à annuler le transfert en cours. Pour annuler un transfert en cours, appelez AbortAsync. L'événement Aborted est déclenché par le code suivant et la connexion pour le périphérique cible est terminé à cette date :

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

Synthèse

L'application de démo est maintenant terminée. Le concept d'apps universelles peut vraiment vous aider dans l'écriture d'un seul morceau de code pour plusieurs plates-formes Windows et facteurs de forme, ce qui réduit l'effort de développement global.

J'ai utilisé ces bibliothèques dans un certain nombre d'apps Store de Windows et Windows Phone. Vous pouvez chercher des Code créer (un Windows Phone App gratuite) ou OBEX (application universelle) et avoir un aperçu du fonctionne entre ces API en conjonction avec l'application. Ces bibliothèques sont disponibles au téléchargement depuis le référentiel NuGet. Recherchez simplement «Bluetooth OBEX pour Store Apps » sur le dialogue en ligne NuGet, directement à partir de la Solution de Visual Studio et ces bibliothèques d'importation comme une référence aux projets.


Uday Gupta est une évolution de l'ingénieur-chef de produit senior chez Symphonie Teleca Corp. Pvt Ltd. en Inde. Il a l'expérience dans de nombreuses technologies .NET, en particulier Windows Presentation Foundation, Silverlight, Windows Phone et Windows 8.x.

Merci aux experts techniques Microsoft suivants d'avoir relu cet article : Jeff Kelley et Guruprasad cassandra