연결 관리

연결 시작

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

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

사용 사례에 따라 검색된 기기 목록을 사용자에게 표시하여 사용자가 연결할 기기를 선택할 수 있도록 하는 것이 좋습니다.

연결 수락 또는 거부

검색자가 광고주와의 연결을 요청한 후 양측은 ConnectionLifecycleCallback 콜백의 onConnectionInitiated() 메서드를 통해 연결 시작 프로세스에 알립니다. 이 콜백은 광고주의 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();
}