영구 클라우드 앵커가 포함된 ARCore 클라우드 앵커

1. 개요

ARCore는 휴대기기에서 증강 현실(AR) 앱을 빌드할 수 있는 플랫폼입니다. Cloud Anchors API를 사용하면 동일한 참조 기준을 사용하는 AR 앱을 만들어 여러 사용자가 동일한 실제 위치에 가상 콘텐츠를 배치하게 할 수 있습니다.

이 Codelab에서는 Cloud Anchors API를 다룹니다. 기존 ARCore 앱을 가져와서 클라우드 앵커를 사용하도록 수정하고 공유 AR 경험을 만듭니다.

ARCore 앵커 및 영구 클라우드 앵커

ARCore의 기본 개념은 실제 세계의 고정된 위치를 설명하는 앵커입니다. 시간이 지나면서 모션 추적이 개선됨에 따라 ARCore가 앵커의 포즈 값을 자동으로 조정합니다.

클라우드 앵커는 클라우드에서 호스팅되는 앵커입니다. 이러한 앵커는 사용자 및 사용자 기기 전반에서 공통된 참조 기준을 설정하기 위해 여러 사용자에 의해 확인될 수 있습니다.

앵커 호스팅

앵커가 호스팅되면 다음과 같은 결과가 발생합니다.

  1. 세상에 관한 앵커의 포즈는 클라우드에 업로드되며 클라우드 앵커 ID를 얻게 됩니다.
    클라우드 앵커 ID는 이 앵커를 확인하려는 모든 사용자에게 전송되어야 하는 문자열입니다.
  2. 앵커를 위한 시각적 데이터가 포함된 데이터 세트가 Google 서버에 업로드됩니다.
    이 데이터 세트에는 기기에서 최근에 본 시각적 데이터가 포함됩니다. 호스팅 전에 서로 다른 관점에서 앵커 주변 공간을 캡처하기 위해 기기를 약간 움직이면 현지화가 개선됩니다.

클라우드 앵커 ID 전송

이 Codelab에서는 Firebase를 사용하여 클라우드 앵커 ID를 전송합니다. 원하는 경우 다른 방법으로 클라우드 앵커 ID를 공유할 수 있습니다.

앵커 확인

Cloud Anchor API를 사용하여 클라우드 앵커 ID를 사용하는 앵커를 확인할 수 있습니다. 이렇게 하면 원래 호스팅된 앵커와 동일한 물리적 위치에 새로운 앵커가 생성됩니다. 확인하는 동안 기기는 원래 호스팅된 앵커와 동일한 물리적 위치를 바라보고 있어야 합니다.

영구 클라우드 앵커

1.20 이전에는 클라우드 앵커를 호스팅 후 24시간 동안만 확인할 수 있었습니다. Persistent Cloud Anchors API를 사용하면 만든 후 1~365일 동안 확인 가능한 클라우드 앵커를 만들 수 있습니다.

빌드할 항목

이 Codelab에서는 기존 ARCore 앱을 기반으로 빌드하겠습니다. Codelab을 마치면 앱에 다음 기능을 구현할 수 있습니다.

  • 영구 클라우드 앵커를 호스팅하고 클라우드 앵커 ID를 가져올 수 있습니다.
  • Android SharedPreferences를 사용하여 쉽게 검색할 수 있도록 기기에 클라우드 앵커 ID를 저장합니다.
  • 저장된 클라우드 앵커 ID를 사용하여 이전에 호스팅된 앵커를 확인합니다. 이렇게 하면 이 Codelab의 목적에 따라 단일 기기로 멀티 사용자 환경을 쉽게 시뮬레이션할 수 있습니다.
  • 클라우드 앵커 ID를 동일한 앱을 실행하는 다른 기기와 공유하면 여러 사용자가 같은 위치에서 Android 동상을 볼 수 있습니다.

Android 동상은 클라우드 앵커의 위치에서 렌더링됩니다.

학습할 내용

  • ARCore SDK를 사용하여 앵커를 호스팅하고 클라우드 앵커 ID를 가져오는 방법
  • 클라우드 앵커 ID를 사용하여 앵커를 확인하는 방법
  • 같은 기기 또는 다른 기기에서 여러 AR 세션 간에 클라우드 앵커 ID를 저장하고 공유하는 방법

필요한 항목

2. 개발 환경 설정

개발 머신 설정

USB 케이블을 통해 ARCore 기기를 컴퓨터에 연결합니다. 기기에서 USB 디버깅을 허용하는지 확인합니다.

터미널을 열고 아래와 같이 adb devices를 실행합니다.

adb devices

List of devices attached
<DEVICE_SERIAL_NUMBER>    device

<DEVICE_SERIAL_NUMBER>는 기기 고유의 문자열입니다. 계속하기 전에 정확히 하나의 기기가 표시되는지 확인하세요.

코드 다운로드 및 설치

저장소를 클론할 수 있습니다.

git clone https://github.com/googlecodelabs/arcore-cloud-anchors.git

또는 ZIP 파일을 다운로드하고 압축을 풉니다.

Android 스튜디오를 실행합니다. 기존 Android 스튜디오 프로젝트 열기를 클릭합니다. 그런 다음 위에서 다운로드한 ZIP 파일의 압축을 푼 디렉터리로 이동하여 arcore-cloud-anchors 디렉터리를 더블클릭합니다.

이 프로젝트는 여러 모듈이 있는 단일 Gradle 프로젝트입니다. Android 스튜디오의 왼쪽 상단에 있는 프로젝트 창에 아직 프로젝트가 표시되지 않으면 드롭다운 메뉴에서 프로젝트를 클릭합니다. 다음과 같은 결과가 표시됩니다.

52282f0415fdbdcb.png

work 모듈에서 주로 작업하게 됩니다. 다른 모듈에는 사용할 유용한 래퍼 클래스 세트가 포함된 helpers 모듈이 포함됩니다. Codelab의 각 부분에 관한 완전한 해결책도 있습니다. helpers 모듈을 제외하고 각 모듈은 빌드 가능한 앱입니다.

Android Gradle 플러그인 업그레이드를 추천하는 대화상자가 표시되면 이 프로젝트에 다시 알림 안함을 클릭합니다.

31a93c7e9cc58b53.png

실행 > 실행… > 'work'를 클릭합니다. 표시되는 배포 대상 선택 대화상자에서 기기가 연결된 기기 아래에 표시되어야 합니다. 기기를 선택하고 확인을 클릭합니다. Android 스튜디오가 기기에서 초기 앱을 빌드하고 실행합니다.

앱을 처음 실행하면 CAMERA 권한을 요청하는 메시지가 나타납니다. 계속하려면 허용을 탭합니다.

f7ea81f71a4b969e.png

앱 사용 방법

  1. 앱이 평면을 찾을 수 있도록 기기를 움직입니다. 평면은 발견 시 점선이 있는 표면으로 표시됩니다.
  2. 평면의 아무 곳이나 탭하여 앵커를 배치합니다. 앵커가 배치된 곳에 Android 그림이 그려집니다. 이 앱에서는 한 번에 하나의 앵커만 배치할 수 있습니다.
  3. 기기를 움직입니다. 기기가 움직이더라도 그림은 같은 위치에 있는 것처럼 표시되어야 합니다.
  4. 앵커를 삭제하려면 지우기 버튼을 누릅니다. 이렇게 하면 다른 앵커를 배치할 수 있습니다.

현재 이 앱은 ARCore에서 제공한 모션 추적만 사용하여 앱을 한 번 실행할 때 앵커를 추적합니다. 앱을 종료하고 닫고 다시 시작하면 이전에 배치된 앵커와 그 포즈를 포함한 관련 정보가 모두 삭제됩니다.

다음 몇 개 섹션에서는 이 앱을 빌드하여 AR 세션 간에 앵커를 공유하는 방법을 알아봅니다.

3. 앵커 호스팅

이 섹션에서는 앵커를 호스팅하기 위해 work 프로젝트를 수정합니다. 코드를 작성하기 전에 앱 구성 몇 가지를 수정해야 합니다.

인터넷 권한 선언

클라우드 앵커는 ARCore Cloud Anchor API 서비스와 통신해야 하므로 앱이 인터넷에 액세스할 수 있어야 합니다.

AndroidManifest.xml 파일에서 android.permission.CAMERA 권한 선언 바로 아래에 다음 줄을 추가합니다.

<!-- Find this line... -->
<uses-permission android:name="android.permission.CAMERA"/>

<!-- Add the line right below -->
<uses-permission android:name="android.permission.INTERNET"/>

ARCore Cloud Anchor API 사용 설정

  1. ARCore Cloud Anchor API 서비스 페이지로 이동합니다.
  2. 프로젝트 목록에서 프로젝트를 선택하거나 새 프로젝트를 만듭니다.
  3. 사용 설정을 클릭합니다.

OAuth 설정

영구 클라우드 앵커를 사용하려면 OAuth를 사용하여 ARCore 클라우드 앵커 서비스로 인증해야 합니다.

  1. Google Cloud Platform Console로 이동합니다.
  2. 프로젝트 목록에서 프로젝트를 선택합니다.
  3. API 및 서비스 페이지가 아직 열려 있지 않다면 Console 왼쪽 메뉴를 열고 API 및 서비스를 선택합니다.
  4. 왼쪽에서 사용자 인증 정보를 클릭합니다.
  5. 사용자 인증 정보 만들기를 클릭하고 OAuth 클라이언트 ID를 선택합니다.
  6. 다음 값을 입력합니다.
    • 애플리케이션 유형: Android
    • 패키지 이름: com.google.ar.core.codelab.cloudanchor
  7. 디버그 서명 인증서 디지털 지문을 검색합니다.
    1. Android 스튜디오 프로젝트에서 Gradle 도구창을 엽니다.
    2. cloud-anchors > work > 태스크 > android에서 signingReport 태스크를 실행합니다.
    3. SHA-1 디지털 지문을 Google Cloud의 SHA-1 인증서 디지털 지문 필드에 복사합니다.

ARCore 구성

다음으로 사용자 탭에서 일반 앵커 대신 호스팅된 앵커를 생성하도록 앱을 수정하겠습니다. 이렇게 하려면 클라우드 앵커를 사용 설정하도록 ARCore 세션을 구성해야 합니다.

CloudAnchorFragment.java 파일에서 다음 코드를 추가합니다.

// Find this line...
session = new Session(requireActivity());

// Add these lines right below:
// Configure the session.
Config config = new Config(session);
config.setCloudAnchorMode(CloudAnchorMode.ENABLED);
session.configure(config);

더 진행하기 전에 앱을 빌드하고 실행합니다. work 모듈만 빌드해야 합니다. 앱이 정상적으로 빌드되고 이전과 동일하게 실행되어야 합니다.

호스팅된 앵커 만들기

이제 ARCore 클라우드 앵커 서비스에 업로드될 호스팅된 앵커를 만들 차례입니다.

CloudAnchorFragment 클래스에 다음 새 필드를 추가합니다.

// Find this line...
private final SnackbarHelper messageSnackbarHelper = new SnackbarHelper();

// Add this line right below.
private final CloudAnchorManager cloudAnchorManager = new CloudAnchorManager();

CloudAnchorManagerSnackbarHelper 클래스가 이미 제공되었습니다. 상용구 코드를 캡슐화하는 몇 가지 유용한 래퍼 클래스이므로 작성한 코드가 훨씬 깔끔하고 간결합니다.

onDrawFrame() 메서드에서 아래에 언급된 줄을 추가합니다.

// Find this line...
Frame frame = session.update();

// Add this line right below:
cloudAnchorManager.onUpdate();

다음과 같이 onClearButtonPressed 메서드를 수정합니다.

private synchronized void onClearButtonPressed() {
  // Clear the anchor from the scene.

  // The next line is the new addition.
  cloudAnchorManager.clearListeners();

  currentAnchor = null;
}

다음으로 CloudAnchorFragment 클래스에 다음 메서드를 추가합니다.

private synchronized void onHostedAnchorAvailable(Anchor anchor) {
  CloudAnchorState cloudState = anchor.getCloudAnchorState();
  if (cloudState == CloudAnchorState.SUCCESS) {
    messageSnackbarHelper.showMessage(
        getActivity(), "Cloud Anchor Hosted. ID: " + anchor.getCloudAnchorId());
    currentAnchor = anchor;
  } else {
    messageSnackbarHelper.showMessage(getActivity(), "Error while hosting: " + cloudState.toString());
  }
}

CloudAnchorFragment 클래스에서 handleTap 메서드를 찾아 다음 줄을 추가합니다.

//Find this line...
currentAnchor = hit.createAnchor();

// Add these lines right below:
messageSnackbarHelper.showMessage(getActivity(), "Now hosting anchor...");
cloudAnchorManager.hostCloudAnchor(session, currentAnchor, /* ttl= */ 300, this::onHostedAnchorAvailable);

Android 스튜디오에서 다시 앱을 실행합니다. 앵커를 배치하면 '현재 앵커 호스팅 중…' 메시지가 표시됩니다. 호스팅이 완료되면 다른 메시지가 표시됩니다. '앵커를 호스팅하는 동안 오류 발생: ERROR_NOT_AUTHORIZED' 메시지가 표시되면 OAuth 클라이언트가 올바르게 구성되었는지 확인하세요.

앵커 ID를 알고 있고 앵커와 동일한 물리적 공간에 있는 사용자는 누구나 앵커 ID를 사용하여 앵커 주위 환경을 기준으로 정확히 동일한 포즈(위치 및 방향)에 앵커를 만들 수 있습니다.

그러나 앵커 ID는 길고 다른 사용자가 수동으로 입력하기가 쉽지 않습니다. 다음 섹션에서는 동일한 기기 또는 다른 기기에서 앵커 확인이 가능하도록 하기 위해 클라우드 앵커 ID를 검색하기 쉬운 방식으로 저장합니다.

4. ID 저장 및 앵커 확인

이 섹션에서는 다른 사용자가 ID를 수동으로 더 쉽게 입력할 수 있도록 긴 클라우드 앵커 ID에 짧은 코드를 할당합니다. Shared Preferences API를 사용하여 클라우드 앵커 ID를 키-값 테이블에 값으로 저장합니다. 이 테이블은 앱이 종료되었다가 다시 시작되더라도 유지됩니다.

StorageManager라는 도우미 클래스가 이미 제공되어 있습니다. SharedPreferences API의 래퍼 클래스로서 고유한 짧은 코드를 새롭게 생성하고 클라우드 앵커 ID를 읽고 쓰는 메서드를 포함하고 있습니다.

StorageManager 사용

짧은 코드로 클라우드 앵커 ID를 저장하기 위해 StorageManager를 사용하도록 CloudAnchorFragment를 수정합니다. 그러면 쉽게 검색할 수 있습니다.

CloudAnchorFragment에 다음 새 필드를 만듭니다.

// Find this line...
private TapHelper tapHelper;

// And add the storageManager.
private final StorageManager storageManager = new StorageManager();

그런 다음 onHostedAnchorAvailable 메서드를 수정합니다.

private synchronized void onHostedAnchorAvailable(Anchor anchor) {
  CloudAnchorState cloudState = anchor.getCloudAnchorState();
  if (cloudState == CloudAnchorState.SUCCESS) {
    int shortCode = storageManager.nextShortCode(getActivity());
    storageManager.storeUsingShortCode(getActivity(), shortCode, anchor.getCloudAnchorId());
    messageSnackbarHelper.showMessage(
        getActivity(), "Cloud Anchor Hosted. Short code: " + shortCode);
    currentAnchor = anchor;
  } else {
    messageSnackbarHelper.showMessage(getActivity(), "Error while hosting: " + cloudState.toString());
  }
}

이제 Android 스튜디오에서 앱을 빌드하고 실행합니다. 앵커를 만들고 호스팅할 때 긴 클라우드 앵커 ID 대신 짧은 코드가 표시됩니다.

앵커 배치 직후

잠시 기다린 후

현재는 StorageManager에 의해 생성된 짧은 코드가 항상 오름차순으로 할당됩니다.

다음으로 짧은 코드를 입력하고 앵커를 다시 만들 수 있는 몇 가지 UI 요소를 추가합니다.

확인 버튼 추가

지우기 버튼 옆에 다른 버튼을 추가합니다. 이 버튼이 확인 버튼이 됩니다. 확인 버튼을 클릭하면 사용자에게 짧은 코드를 입력하라는 대화상자가 열립니다. 짧은 코드를 사용하여 StorageManager에서 클라우드 앵커 ID를 검색하고 앵커를 확인합니다.

버튼을 추가하려면 res/layout/cloud_anchor_fragment.xml 파일을 수정해야 합니다. Android 스튜디오에서 파일을 더블클릭한 다음 하단의 '텍스트' 탭을 클릭하여 원시 XML을 표시합니다. 다음과 같이 수정합니다.

<!-- Find this element. -->
<Button
    android:text="CLEAR"
    android:id="@+id/clear_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

<!-- Add this element right below. -->
<Button
    android:text="RESOLVE"
    android:id="@+id/resolve_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

이제 CloudAnchorFragment에 새 필드를 추가합니다.

private Button resolveButton;

새 메서드를 추가합니다.

private synchronized void onResolveButtonPressed() {
  ResolveDialogFragment dialog = new ResolveDialogFragment();
  dialog.show(getFragmentMagetActivity().getSupportFragmentManagernager(), "Resolve");
}

다음과 같이 onCreateView 메서드에서 resolveButton을 초기화합니다.

// Find these lines...
Button clearButton = rootView.findViewById(R.id.clear_button);
clearButton.setOnClickListener(v -> onClearButtonPressed());

// Add these lines right below.
resolveButton = rootView.findViewById(R.id.resolve_button);
resolveButton.setOnClickListener(v -> onResolveButtonPressed());

handleTap 메서드를 찾아 수정합니다.

private void handleTap(Frame frame, Camera camera) {
  // ...

  // Find this line.
  currentAnchor = hit.createAnchor();

  // Add this line right below.
  getActivity().runOnUiThread(() -> resolveButton.setEnabled(false));
}

onClearButtonPressed 메서드에 줄을 추가합니다.

private synchronized void onClearButtonPressed() {
  // Clear the anchor from the scene.
  cloudAnchorManager.clearListeners();

  // The next line is the new addition.
  resolveButton.setEnabled(true);

  currentAnchor = null;
}

Android 스튜디오에서 앱을 빌드하고 실행합니다. 지우기 버튼 옆에 확인 버튼이 표시됩니다. 확인 버튼을 클릭하면 아래와 같이 대화상자가 나타납니다.

이제 확인 버튼이 표시됩니다.

이 버튼을 클릭하면 다음과 같은 대화상자가 표시됩니다.

평면을 탭하고 앵커를 호스팅하면 확인 버튼이 사용 중지되지만 지우기 버튼을 탭하면 다시 사용 설정됩니다. 이는 한 번에 하나의 앵커만 장면에 포함되도록 하기 위해 의도적으로 설계된 것입니다.

'앵커 확인' 대화상자에서는 아무 작업도 하지 않지만 이제 변경할 것입니다.

앵커 확인

CloudAnchorFragment 클래스에 다음 메서드를 추가합니다.

private synchronized void onShortCodeEntered(int shortCode) {
  String cloudAnchorId = storageManager.getCloudAnchorId(getActivity(), shortCode);
  if (cloudAnchorId == null || cloudAnchorId.isEmpty()) {
    messageSnackbarHelper.showMessage(
        getActivity(),
        "A Cloud Anchor ID for the short code " + shortCode + " was not found.");
    return;
  }
  resolveButton.setEnabled(false);
  cloudAnchorManager.resolveCloudAnchor(
      session,
      cloudAnchorId,
      anchor -> onResolvedAnchorAvailable(anchor, shortCode));
}

private synchronized void onResolvedAnchorAvailable(Anchor anchor, int shortCode) {
  CloudAnchorState cloudState = anchor.getCloudAnchorState();
  if (cloudState == CloudAnchorState.SUCCESS) {
    messageSnackbarHelper.showMessage(getActivity(), "Cloud Anchor Resolved. Short code: " + shortCode);
    currentAnchor = anchor;
  } else {
    messageSnackbarHelper.showMessage(
        getActivity(),
        "Error while resolving anchor with short code " + shortCode + ". Error: "
            + cloudState.toString());
    resolveButton.setEnabled(true);
  }
}

그런 다음 onResolveButtonPressed 메서드를 수정합니다.

private synchronized void onResolveButtonPressed() {
  ResolveDialogFragment dialog = ResolveDialogFragment.createWithOkListener(
      this::onShortCodeEntered);
  dialog.show(getActivity().getSupportFragmentManager(), "Resolve");
}

Android 스튜디오에서 앱을 빌드하고 실행한 후 다음 단계를 실행합니다.

  1. 평면에 앵커를 만들고 앵커가 호스팅될 때까지 기다립니다.
    짧은 코드를 기억하세요.
  2. 지우기 버튼을 눌러 앵커를 삭제합니다.
  3. 확인 버튼을 누릅니다. 1단계의 짧은 코드를 입력합니다.
  4. 처음 배치한 환경을 기준으로 동일한 위치에 앵커가 표시되어야 합니다.
  5. 앱을 종료하고 닫았다가 다시 엽니다.
  6. 3단계와 4단계를 반복합니다. 같은 위치에 새 앵커가 다시 표시됩니다.

짧은 코드 입력

앵커가 확인됨

5. 기기 간 공유

앵커의 클라우드 앵커 ID를 기기의 로컬 저장소에 저장하고 나중에 이를 검색하여 동일한 앵커를 다시 만드는 방법을 알아보았습니다. 하지만 클라우드 앵커의 모든 기능은 서로 다른 기기 간에 클라우드 앵커 ID를 공유할 수 있을 때만 사용할 수 있습니다.

앱에서 클라우드 앵커 ID를 공유하는 방법은 개발자가 정합니다. 한 기기에서 다른 기기로 문자열을 전송하기 위해 어떤 방법이든 사용할 수 있습니다. 이 Codelab에서는 Firebase 실시간 데이터베이스를 사용하여 앱 인스턴스 간에 클라우드 앵커 ID를 전송합니다.

Firebase 설정

이 앱에서 사용할 Google 계정으로 Firebase 실시간 데이터베이스를 설정해야 합니다. Android 스튜디오의 Firebase Assistant를 사용하면 간단합니다.

Android 스튜디오에서 도구 > Firebase를 클릭합니다. 표시되는 어시스턴트 창에서 실시간 데이터베이스를 클릭한 후 데이터 저장 및 검색을 클릭합니다.

68e927cbf324a3b2.png

Firebase에 연결 버튼을 클릭하여 Android 스튜디오 프로젝트를 새 Firebase 프로젝트 또는 기존 Firebase 프로젝트에 연결합니다.

63f3b1ffd6bd263e.png

그러면 모듈을 선택하라는 메시지가 표시됩니다. work 모듈을 선택합니다.

be737c689ad6dd78.png

연결 시작 대화상자가 표시됩니다. 이 작업은 다소 시간이 걸릴 수 있습니다.

b48626f8672551ee.png

Google 계정으로 로그인하고 Android 스튜디오로 돌아갈 때까지 앱의 Firebase 프로젝트를 만드는 웹 워크플로를 진행합니다.

그런 다음 어시스턴트 창에서 실시간 데이터베이스를 앱에 연결을 클릭합니다.

68e0843fa2531c4c.png

표시되는 대화상자의 대상 모듈 드롭다운에서 work를 선택한 후 변경 수락을 클릭합니다.

155fd89533c02671.png

다음 단계를 따르세요.

  1. work 디렉터리에 google-services.json 파일을 추가합니다.
  2. 동일한 디렉터리의 build.gradle 파일에 몇 줄을 추가합니다.
  3. 앱을 빌드하고 실행합니다. Firebase 데이터베이스 버전 번호에 관한 확인 오류가 표시될 수도 있습니다.

work 모듈의 build.gradle 파일에서 다음 줄을 찾아 삭제합니다(xxxx는 최신 버전 번호의 자리표시자임).

dependencies {
  ...
  implementation 'com.google.firebase:firebase-database:xxxx'

그런 다음 공개 액세스 규칙 구성 페이지에 링크된 안내를 검토하고(아직 따르지는 않음) Firebase 실시간 데이터베이스를 누구나 쓸 수 있도록 구성합니다. 이렇게 하면 이 Codelab에서 테스트를 간소화하는 데 도움이 됩니다.

666ebefd39019c05.png

Firebase Console에서 Android 스튜디오 프로젝트를 연결한 프로젝트를 선택한 다음 빌드 > 실시간 데이터베이스를 선택합니다.

Firebase 실시간 데이터베이스 위치

데이터베이스 만들기를 클릭하여 실시간 데이터베이스를 구성 및 설정합니다.

데이터베이스 만들기

데이터베이스 위치를 선택합니다.

다음 단계에서 테스트 모드 보안 규칙을 선택하고 사용 설정을 클릭합니다.

데이터베이스 보안

이제 앱이 Firebase 데이터베이스를 사용하도록 구성되었습니다.

FirebaseManager 사용

이제 StorageManagerFirebaseManager로 바꿉니다.

Android 스튜디오의 work 디렉터리 아래에서 CloudAnchorFragment 클래스를 찾습니다. StorageManagerFirebaseManager로 바꿉니다.

// Find this line.
private final StorageManager storageManager = new StorageManager();

// And replace it with this line.
private FirebaseManager firebaseManager;

onAttach 메서드에서 firebaseManager를 초기화합니다.

public void onAttach(@NonNull Context context) {
  super.onAttach(context);
  tapHelper = new TapHelper(context);
  trackingStateHelper = new TrackingStateHelper(requireActivity());

  // The next line is the new addition.
  firebaseManager = new FirebaseManager(context);
}

다음과 같이 onShortCodeEntered 메서드를 수정합니다.

private synchronized void onShortCodeEntered(int shortCode) {
  firebaseManager.getCloudAnchorId(shortCode, cloudAnchorId -> {
    if (cloudAnchorId == null || cloudAnchorId.isEmpty()) {
      messageSnackbarHelper.showMessage(
          getActivity(),
          "A Cloud Anchor ID for the short code " + shortCode + " was not found.");
      return;
    }
    resolveButton.setEnabled(false);
    cloudAnchorManager.resolveCloudAnchor(
        session,
        cloudAnchorId,
        anchor -> onResolvedAnchorAvailable(anchor, shortCode));
  });
}

그런 다음 onHostedAnchorAvailable 메서드를 다음과 같이 수정합니다.

private synchronized void onHostedAnchorAvailable(Anchor anchor) {
  CloudAnchorState cloudState = anchor.getCloudAnchorState();
  if (cloudState == CloudAnchorState.SUCCESS) {
    String cloudAnchorId = anchor.getCloudAnchorId();
    firebaseManager.nextShortCode(shortCode -> {
      if (shortCode != null) {
        firebaseManager.storeUsingShortCode(shortCode, cloudAnchorId);
        messageSnackbarHelper.showMessage(getActivity(), "Cloud Anchor Hosted. Short code: " + shortCode);
      } else {
        // Firebase could not provide a short code.
        messageSnackbarHelper.showMessage(getActivity(), "Cloud Anchor Hosted, but could not "
                + "get a short code from Firebase.");
      }
    });
    currentAnchor = anchor;
  } else {
    messageSnackbarHelper.showMessage(getActivity(), "Error while hosting: " + cloudState.toString());
  }
}

앱을 빌드하고 실행합니다. 이제 이전 섹션과 동일한 UI 흐름이 표시됩니다. 단, 현재는 기기의 로컬 스토리지 대신 온라인 Firebase 데이터베이스를 사용하여 클라우드 앵커 ID와 짧은 코드를 저장합니다.

멀티 사용자 테스트

멀티 사용자 환경을 테스트하려면 휴대전화 2대를 사용해야 합니다.

  1. 두 기기에 앱을 설치합니다.
  2. 한 기기를 사용하여 앵커를 호스팅하고 짧은 코드를 생성합니다.
  3. 다른 기기를 사용하여 이 짧은 코드로 앵커를 확인합니다.

한 기기에서 앵커를 호스팅하고 짧은 코드를 가져온 다음 다른 기기에서 짧은 코드를 사용하여 동일한 위치에 앵커를 표시할 수 있어야 합니다.

6. 마무리

축하합니다. 이 Codelab을 완료했습니다.

학습한 내용

  • ARCore SDK를 사용하여 앵커를 호스팅하고 클라우드 앵커 ID를 가져오는 방법
  • 클라우드 앵커 ID를 사용하여 앵커를 확인하는 방법
  • 같은 기기 또는 다른 기기에서 여러 AR 세션 간에 클라우드 앵커 ID를 저장하고 공유하는 방법

자세히 알아보기