Administra conexiones

Inicia una conexión

Cuando se encuentran dispositivos cercanos, el descubridor puede iniciar conexiones. En el siguiente ejemplo, se solicita una conexión con un dispositivo en cuanto se descubre.

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

Según tu caso práctico, puedes mostrar al usuario una lista de los dispositivos detectados para que pueda elegir a qué dispositivos conectarse.

Aceptar o rechazar una conexión

Después de que el descubrimiento solicita una conexión a un anunciante, ambas partes reciben una notificación del proceso de inicio de la conexión a través del método onConnectionInitiated() de la devolución de llamada ConnectionLifecycleCallback. Ten en cuenta que esta devolución de llamada se pasa a startAdvertising() en el anunciante y a requestConnection() en el detector, pero a partir de ese momento, la API es simétrica.

Ahora ambas partes deben elegir si desean aceptar o rechazar la conexión a través de una llamada a acceptConnection() o rejectConnection(), respectivamente. La conexión se establece por completo solo cuando ambas partes aceptan. Si uno o ambos se rechazan, se descarta la conexión. De cualquier manera, el resultado se entrega a onConnectionResult().

En el siguiente fragmento de código, se muestra cómo implementar esta devolución de llamada:

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

Una vez más, en este ejemplo se muestra que la conexión es aceptada automáticamente por ambos lados, pero, según tu caso de uso, tal vez quieras presentarle esta opción al usuario de alguna manera.

Autentica una conexión

Cuando se solicita una conexión, tu app puede autenticar la conexión mediante el token de autenticación proporcionado para onConnectionInitiated(). Esto permite que los usuarios confirmen que se están conectando al dispositivo deseado. Ambos dispositivos reciben el mismo token, que es una string corta aleatoria. Tú decides cómo verificarlo. Por lo general, esto implica mostrar el token en ambos dispositivos y pedirles a los usuarios que comparen y confirmen manualmente, de forma similar al diálogo de vinculación por Bluetooth.

En este código de muestra, se muestra una forma de autenticación cuando se muestra el token de autenticación al usuario en 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();
}