Verbindungen verwalten

Verbindung herstellen

Wenn Geräte in der Nähe gefunden werden, kann der Finder Verbindungen herstellen. Im folgenden Beispiel wird eine Verbindung mit einem Gerät angefordert, sobald dieses erkannt wird.

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

Je nach Anwendungsfall möchten Sie dem Nutzer stattdessen eine Liste der erkannten Geräte anzeigen lassen, damit er auswählen kann, zu welchen Geräten eine Verbindung hergestellt werden soll.

Verbindung akzeptieren oder ablehnen

Nachdem der Discovery eine Verbindung zu einem Werbetreibenden angefordert hat, werden beide Seiten über die Methode onConnectionInitiated() des ConnectionLifecycleCallback-Callbacks über den Startvorgang informiert. Dieser Callback wird an startAdvertising() an den Werbetreibenden und requestConnection() an den Finder übergeben. Ab diesem Zeitpunkt ist die API jedoch symmetrisch.

Jetzt müssen beide Seiten die Verbindung über einen Aufruf von acceptConnection() bzw. rejectConnection() annehmen oder ablehnen. Die Verbindung wird erst dann vollständig hergestellt, wenn beide Seiten akzeptiert wurden. Wenn eine oder beide abgelehnt werden, wird die Verbindung verworfen. In beiden Fällen wird das Ergebnis an onConnectionResult() gesendet.

Das folgende Code-Snippet zeigt, wie dieser Callback implementiert wird:

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

Auch hier wird wieder gezeigt, dass die Verbindung von beiden Seiten automatisch akzeptiert wird. Je nach Anwendungsfall kann es jedoch sinnvoll sein, diese Option dem Nutzer zu zeigen.

Verbindung authentifizieren

Wenn eine Verbindung angefordert wird, kann die Anwendung die Verbindung mithilfe des für onConnectionInitiated() angegebenen Authentifizierungstokens authentifizieren. So können Nutzer bestätigen, dass sie sich mit dem gewünschten Gerät verbinden. Beide Geräte erhalten das gleiche Token, einen kurzen zufälligen String. Du musst entscheiden, wie du es verifizieren möchtest. Dazu wird normalerweise das Token auf beiden Geräten angezeigt und die Nutzer werden gebeten, sie manuell zu vergleichen und zu bestätigen, ähnlich wie bei einem Bluetooth-Kopplungsdialogfeld.

Dieser Beispielcode zeigt eine Möglichkeit zur Authentifizierung, indem dem Nutzer das Authentifizierungstoken in einem AlertDialog angezeigt wird:

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