연결 관리

연결 시작

근처 기기가 발견되면 발견자가 연결을 시작할 수 있습니다. 이 다음 예는 기기가 검색되는 즉시 장치와의 연결을 요청합니다.

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()에 대해 입찰했지만, 이 지점부터는 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()에 제공된 인증 토큰 사용 이 사용자가 의도한 있습니다. 두 기기에 동일한 토큰(짧은 임의의 문자열)이 제공됩니다. 인증 방법을 결정하는 것은 사용자의 몫입니다. 일반적으로 이를 위해서는 두 기기에서 모두 사용하고 사용자에게 수동으로 비교 및 확인하도록 요청할 수 있습니다. 블루투스 페어링 대화상자와 비슷합니다.

이 샘플 코드는 인증 토큰을 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();
}