Gérer les connexions

Établissez une connexion

Lorsque des appareils à proximité sont détectés, l'explorateur peut établir des connexions. L'exemple suivant demande une connexion avec un appareil dès sa découverte.

private final EndpointDiscoveryCallback endpointDiscoveryCallback =
    new EndpointDiscoveryCallback() {
      @Override
      public void onEndpointFound(String endpointId, DiscoveredEndpointInfo info) {
        // An endpoint was found. We request a connection to it.
        Nearby.getConnectionsClient(context)
            .requestConnection(getLocalUserName(), endpointId, connectionLifecycleCallback)
            .addOnSuccessListener(
                (Void unused) -> {
                  // We successfully requested a connection. Now both sides
                  // must accept before the connection is established.
                })
            .addOnFailureListener(
                (Exception e) -> {
                  // Nearby Connections failed to request the connection.
                });
      }

      @Override
      public void onEndpointLost(String endpointId) {
        // A previously discovered endpoint has gone away.
      }
    };

En fonction de votre cas d'utilisation, vous pouvez présenter à l'utilisateur la liste des appareils découverts, lui permettant de choisir les appareils auxquels se connecter.

Accepter ou refuser une connexion

Une fois que le découverte a demandé une connexion à un annonceur, les deux côtés sont informés du processus d'initiation de connexion via la méthode onConnectionInitiated() du rappel ConnectionLifecycleCallback. Notez que ce rappel est transmis à startAdvertising() sur l'annonceur et requestConnection() sur le système de découverte, mais à partir de ce moment, l'API est symétrique.

Les deux côtés doivent maintenant accepter ou refuser la connexion via un appel à acceptConnection() ou rejectConnection(), respectivement. La connexion n'est entièrement établie que lorsque les deux parties l'ont acceptée. Si l'une des méthodes ou les deux refusent, la connexion est supprimée. Dans tous les cas, le résultat est transmis à onConnectionResult().

L'extrait de code suivant montre comment implémenter ce rappel:

private final ConnectionLifecycleCallback connectionLifecycleCallback =
    new ConnectionLifecycleCallback() {
      @Override
      public void onConnectionInitiated(String endpointId, ConnectionInfo connectionInfo) {
        // Automatically accept the connection on both sides.
        Nearby.getConnectionsClient(context).acceptConnection(endpointId, payloadCallback);
      }

      @Override
      public void onConnectionResult(String endpointId, ConnectionResolution result) {
        switch (result.getStatus().getStatusCode()) {
          case ConnectionsStatusCodes.STATUS_OK:
            // We're connected! Can now start sending and receiving data.
            break;
          case ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED:
            // The connection was rejected by one or both sides.
            break;
          case ConnectionsStatusCodes.STATUS_ERROR:
            // The connection broke before it was able to be accepted.
            break;
          default:
            // Unknown status code
        }
      }

      @Override
      public void onDisconnected(String endpointId) {
        // We've been disconnected from this endpoint. No more data can be
        // sent or received.
      }
    };

Dans cet exemple, la connexion est automatiquement acceptée des deux côtés, mais selon votre cas d'utilisation, vous voudrez peut-être présenter votre choix à l'utilisateur.

Authentifier une connexion

Lorsqu'une connexion est demandée, votre application peut authentifier la connexion à l'aide du jeton d'authentification fourni à onConnectionInitiated(). Cela permet aux utilisateurs de confirmer qu'ils se connectent à l'appareil prévu. Les deux appareils reçoivent le même jeton, qui est une courte chaîne aléatoire. C'est à vous de décider comment le valider. En règle générale, cela implique d'afficher le jeton sur les deux appareils et de demander aux utilisateurs de comparer et de confirmer manuellement, comme une boîte de dialogue d'association Bluetooth.

Cet exemple de code illustre une façon d'authentifier en affichant le jeton d'authentification à l'utilisateur dans un AlertDialog :

@Override
public void onConnectionInitiated(String endpointId, ConnectionInfo info) {
  new AlertDialog.Builder(context)
      .setTitle("Accept connection to " + info.getEndpointName())
      .setMessage("Confirm the code matches on both devices: " + info.getAuthenticationDigits())
      .setPositiveButton(
          "Accept",
          (DialogInterface dialog, int which) ->
              // The user confirmed, so we can accept the connection.
              Nearby.getConnectionsClient(context)
                  .acceptConnection(endpointId, payloadCallback))
      .setNegativeButton(
          android.R.string.cancel,
          (DialogInterface dialog, int which) ->
              // The user canceled, so we should reject the connection.
              Nearby.getConnectionsClient(context).rejectConnection(endpointId))
      .setIcon(android.R.drawable.ic_dialog_alert)
      .show();
}