إدارة الاتصالات

بدء اتصال

عند العثور على أجهزة قريبة، يمكن لأداة الرصد بدء الاتصالات. يطلب المثال التالي الاتصال بجهاز فور اكتشافه.

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. يُرجى العلم بأن معاودة الاتصال هذه تم تمريرها إلى startAdvertising() على المعلن وrequestConnection() على أداة الاكتشاف، ولكن من الآن فصاعدًا، واجهة برمجة التطبيقات متماثلة.

يجب على كلا الطرفين الآن اختيار ما إذا كان سيتم قبول الاتصال أو رفضه عبر مكالمة إلى 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(). وهذا يوفر طريقة لتسمح للمستخدمين بتأكيد اتصالهم بالجهاز المقصود. ويُمنح كلا الجهازين الرمز المميز نفسه، وهو عبارة عن سلسلة عشوائية قصيرة؛ ويترك الأمر لك لتحديد كيفية التحقق منه. ويتضمن هذا عادةً عرض الرمز المميّز على كلا الجهازين ومطالبة المستخدمين بالمقارنة والتأكيد يدويًا، على غرار مربع حوار إقران البلوتوث.

يوضح نموذج الرمز هذا طريقة واحدة للمصادقة من خلال عرض الرمز المميز للمصادقة للمستخدم في 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();
}