Gestisci connessioni

Avvia una connessione

Quando vengono trovati dispositivi nelle vicinanze, il rilevatore può avviare le connessioni. L'esempio seguente richiede la connessione a un dispositivo non appena viene rilevato.

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

A seconda del caso d'uso, potresti voler mostrare all'utente un elenco di dispositivi rilevati, consentendogli di scegliere a quali dispositivi connettersi.

Accettare o rifiutare una connessione

Dopo che il scopritore ha richiesto una connessione a un inserzionista, entrambe le parti vengono informate del processo di avvio della connessione tramite il metodo onConnectionInitiated() del callback ConnectionLifecycleCallback. Tieni presente che questo callback viene trasmesso a startAdvertising() nell'inserzionista e in requestConnection() nello strumento di rilevamento, ma da questo momento in poi l'API è simmetrica.

Ora entrambe le parti devono scegliere se accettare o rifiutare la connessione utilizzando rispettivamente una chiamata al numero acceptConnection() o al numero rejectConnection(). La connessione viene stabilita interamente solo quando entrambe le parti hanno accettato. Se una o entrambe le rifiuti, la connessione viene ignorata. In entrambi i casi, il risultato viene consegnato a onConnectionResult().

Il seguente snippet di codice mostra come implementare questo callback:

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

Anche in questo esempio viene mostrata la connessione accettata automaticamente da entrambi i lati, ma a seconda del caso d'uso potresti voler presentare questa scelta all'utente in qualche modo.

Autenticare una connessione

Quando viene richiesta una connessione, la tua app può autenticarla utilizzando il token di autenticazione fornito a onConnectionInitiated(). In questo modo gli utenti possono confermare che si stanno connettendo al dispositivo previsto. A entrambi i dispositivi viene assegnato lo stesso token, che è una breve stringa casuale. Sta a te decidere come verificarlo. In genere ciò significa mostrare il token su entrambi i dispositivi e chiedere agli utenti di confrontare e confermare manualmente la procedura, in modo simile a una finestra di dialogo per l'accoppiamento Bluetooth.

Questo codice campione mostra un modo per eseguire l'autenticazione visualizzando il token di autenticazione per l'utente in 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();
}