ניהול החיבורים

יצירת חיבור

כשמאתרים מכשירים בקרבת מקום, ה-Discovery יכול להתחיל חיבורים. הדוגמה הבאה מבקשת חיבור למכשיר ברגע שהוא מתגלה.

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

בהתאם לתרחיש לדוגמה שלכם, ייתכן שתרצו להציג רשימה של מכשירים שהתגלו בפני המשתמש, וכך לאפשר לו לבחור לאילו מכשירים להתחבר.

אישור או דחייה של חיבור

כשהמגלה ביקש חיבור למפרסם, שני הצדדים מקבלים הודעה על תהליך הפעלת החיבור בשיטה onConnectionInitiated() של הקריאה החוזרת ConnectionLifecycleCallback. שימו לב שהקריאה החוזרת (callback) מועברת ל-startAdvertising() אצל המפרסם ול-requestConnection() בכלי הגילוי, אבל מאותו רגע ה-API הוא סימטרי.

עכשיו שני הצדדים צריכים לבחור אם לאשר או לדחות את הבקשה דרך acceptConnection() או rejectConnection(), בהתאמה. החיבור נוצר במלואו רק כאשר שני הצדדים אישרו אותו. אם אחת מהן או שתיהן נדחו, החיבור נמחק. בכל מקרה, התוצאה תגיע אל onConnectionResult().

קטע הקוד הבא מראה איך להטמיע את הקריאה החוזרת הזו:

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

שוב, הדוגמה הזו מציגה את החיבור המתקבל באופן אוטומטי על ידי שני הצדדים, אבל בהתאם לתרחיש לדוגמה שלכם, כדאי להציג את הבחירה הזו למשתמש באופן מסוים.

אימות חיבור

כשמתבקש חיבור, האפליקציה יכולה לאמת את החיבור באמצעות אסימון האימות שסופק ל-onConnectionInitiated(). כך המשתמשים יכולים לאשר שהם מתחברים למכשיר הרצוי. שני המכשירים מקבלים את אותו אסימון, שהוא מחרוזת אקראית קצרה. אתם קובעים איך לאמת אותו. בדרך כלל צריך להציג את האסימון בשני המכשירים ולבקש מהמשתמשים להשוות ולאשר באופן ידני, בדומה לתיבת דו-שיח להתאמת Bluetooth.

קוד לדוגמה זה מדגים דרך אחת לאימות, על ידי הצגת אסימון האימות למשתמש ב-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();
}