인앱 리뷰 통합(네이티브)

이 가이드에서는 네이티브(C 또는 C++) 코드를 사용하여 인앱 리뷰를 앱에 통합하는 방법을 설명합니다. Kotlin이나 자바 또는 Unity를 사용한다면 별도의 통합 가이드가 있습니다.

네이티브 SDK 개요

Play Core Native SDK는 Google Play Core 라이브러리 제품군의 일부입니다. Play Core Native SDK에는 Java Play In-App Review 라이브러리에서 ReviewManager를 래핑하는 C 헤더 파일 review.h가 포함되어 있습니다. 이 헤더 파일을 사용하면 앱이 네이티브 코드에서 직접 API를 호출할 수 있습니다. 사용할 수 있는 공개 함수에 관한 개요는 Play 리뷰 네이티브 모듈 문서를 참고하세요.

ReviewManager_requestReviewFlow는 나중에 인앱 리뷰 흐름을 실행하는 데 필요한 정보를 수집하는 요청을 시작합니다. ReviewManager_getReviewStatus를 사용하여 요청 결과를 추적할 수 있습니다. ReviewManager_getReviewStatus에서 반환할 수 있는 모든 상태에 관한 자세한 내용은 ReviewErrorCode를 참고하세요.

함수가 성공하면 요청 함수와 실행 함수 모두 REVIEW_NO_ERROR를 반환합니다.

개발 환경 설정

다운로드 Play Core Native SDK

다운로드하기 전에 다음 이용약관에 동의해야 합니다.

이용약관

Last modified: September 24, 2020
  1. By using the Play Core Software Development Kit, you agree to these terms in addition to the Google APIs Terms of Service ("API ToS"). If these terms are ever in conflict, these terms will take precedence over the API ToS. Please read these terms and the API ToS carefully.
  2. For purposes of these terms, "APIs" means Google's APIs, other developer services, and associated software, including any Redistributable Code.
  3. “Redistributable Code” means Google-provided object code or header files that call the APIs.
  4. Subject to these terms and the terms of the API ToS, you may copy and distribute Redistributable Code solely for inclusion as part of your API Client. Google and its licensors own all right, title and interest, including any and all intellectual property and other proprietary rights, in and to Redistributable Code. You will not modify, translate, or create derivative works of Redistributable Code.
  5. Google may make changes to these terms at any time with notice and the opportunity to decline further use of the Play Core Software Development Kit. Google will post notice of modifications to the terms at https://developer.android.com/guide/playcore/license. Changes will not be retroactive.
다운로드 Play Core Native SDK

play-core-native-sdk-1.15.3.zip

  1. 다음 중 하나를 실행합니다.

    • Android 스튜디오 버전 4.0 이상을 설치합니다. SDK Manager UI를 사용하여 Android SDK 플랫폼 버전 10.0(API 수준 29)을 설치합니다.
    • Android SDK 명령줄 도구를 설치하고 sdkmanager를 사용하여 Android SDK 플랫폼 버전 10.0(API 수준 29)을 설치합니다.
  2. SDK Manager를 사용하여 최신 CMake 및 Android 네이티브 개발 키트(NDK)를 설치함으로써 네이티브 개발을 위해 Android 스튜디오를 준비합니다. 네이티브 프로젝트를 만들거나 가져오는 방법에 관한 자세한 내용은 NDK 시작하기를 참고하세요.

  3. ZIP 파일을 다운로드하여 프로젝트와 함께 압축을 풉니다.

    다운로드 링크 크기 SHA-256 체크섬
    37.8MiB 9db60185185342f28d2c278b60222333608c67bc022e458a25224eaea8c4c4b7
  4. 아래와 같이 앱의 build.gradle 파일을 업데이트합니다.

    Groovy

        // App build.gradle
    
        plugins {
          id 'com.android.application'
        }
    
        // Define a path to the extracted Play Core SDK files.
        // If using a relative path, wrap it with file() since CMake requires absolute paths.
        def playcoreDir = file('../path/to/playcore-native-sdk')
    
        android {
            defaultConfig {
                ...
                externalNativeBuild {
                    cmake {
                        // Define the PLAYCORE_LOCATION directive.
                        arguments "-DANDROID_STL=c++_static",
                                  "-DPLAYCORE_LOCATION=$playcoreDir"
                    }
                }
                ndk {
                    // Skip deprecated ABIs. Only required when using NDK 16 or earlier.
                    abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
                }
            }
            buildTypes {
                release {
                    // Include Play Core Library proguard config files to strip unused code while retaining the Java symbols needed for JNI.
                    proguardFile '$playcoreDir/proguard/common.pgcfg'
                    proguardFile '$playcoreDir/proguard/gms_task.pgcfg'
                    proguardFile '$playcoreDir/proguard/per-feature-proguard-files'
                    ...
                }
                debug {
                    ...
                }
            }
            externalNativeBuild {
                cmake {
                    path 'src/main/CMakeLists.txt'
                }
            }
        }
    
        dependencies {
            // Import these feature-specific AARs for each Google Play Core library.
            implementation 'com.google.android.play:app-update:2.1.0'
            implementation 'com.google.android.play:asset-delivery:2.2.2'
            implementation 'com.google.android.play:integrity:1.4.0'
            implementation 'com.google.android.play:review:2.0.2'
    
            // Import these common dependencies.
            implementation 'com.google.android.gms:play-services-tasks:18.0.2'
            implementation files("$playcoreDir/playcore-native-metadata.jar")
            ...
        }
        

    Kotlin

    // App build.gradle
    
    plugins {
        id("com.android.application")
    }
    
    // Define a path to the extracted Play Core SDK files.
    // If using a relative path, wrap it with file() since CMake requires absolute paths.
    val playcoreDir = file("../path/to/playcore-native-sdk")
    
    android {
        defaultConfig {
            ...
            externalNativeBuild {
                cmake {
                    // Define the PLAYCORE_LOCATION directive.
                    arguments += listOf("-DANDROID_STL=c++_static", "-DPLAYCORE_LOCATION=$playcoreDir")
                }
            }
            ndk {
                // Skip deprecated ABIs. Only required when using NDK 16 or earlier.
                abiFilters.clear()
                abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
            }
        }
        buildTypes {
            release {
                // Include Play Core Library proguard config files to strip unused code while retaining the Java symbols needed for JNI.
                proguardFile("$playcoreDir/proguard/common.pgcfg")
                proguardFile("$playcoreDir/proguard/gms_task.pgcfg")
                proguardFile("$playcoreDir/proguard/per-feature-proguard-files")
                ...
            }
            debug {
                ...
            }
        }
        externalNativeBuild {
            cmake {
                path = "src/main/CMakeLists.txt"
            }
        }
    }
    
    dependencies {
        // Import these feature-specific AARs for each Google Play Core library.
        implementation("com.google.android.play:app-update:2.1.0")
        implementation("com.google.android.play:asset-delivery:2.2.2")
        implementation("com.google.android.play:integrity:1.4.0")
        implementation("com.google.android.play:review:2.0.2")
    
        // Import these common dependencies.
        implementation("com.google.android.gms:play-services-tasks:18.0.2")
        implementation(files("$playcoreDir/playcore-native-metadata.jar"))
        ...
    }
  5. 아래와 같이 앱의 CMakeLists.txt 파일을 업데이트합니다.

    cmake_minimum_required(VERSION 3.6)
    
    ...
    
    # Add a static library called “playcore” built with the c++_static STL.
    include(${PLAYCORE_LOCATION}/playcore.cmake)
    add_playcore_static_library()
    
    // In this example “main” is your native code library, i.e. libmain.so.
    add_library(main SHARED
            ...)
    
    target_include_directories(main PRIVATE
            ${PLAYCORE_LOCATION}/include
            ...)
    
    target_link_libraries(main
            android
            playcore
            ...)
    

데이터 수집

Play Core Native SDK는 Google에서 제품을 개선할 수 있도록 다음과 같은 버전 관련 데이터를 수집할 수 있습니다.

  • 앱의 패키지 이름
  • 앱의 패키지 버전
  • Play Core Native SDK 버전

이 데이터는 앱 패키지를 Play Console에 업로드할 때 수집됩니다. 이 데이터 수집 프로세스를 선택 해제하려면 build.gradle 파일에서 $playcoreDir/playcore-native-metadata.jar 가져오기를 삭제합니다.

Play Core Native SDK 사용 및 Google의 수집된 데이터 사용과 관련된 이 데이터 수집은 앱 패키지를 Play Console에 업로드할 때 Gradle에 선언된 라이브러리 종속 항목에 관한 Google의 수집과는 별개이며 관련이 없습니다.

Play Core Native SDK를 프로젝트에 통합한 후 API 호출이 포함된 파일에 다음 줄을 포함합니다.

review.h 포함

Play Core Native SDK를 프로젝트에 통합한 후 API 호출이 포함될 파일에 다음 줄을 포함합니다.

#include "play/review.h"

Review API 초기화

언제든지 API를 사용하려면 android_native_app_glue.h로 빌드된 다음 예와 같이 먼저 ReviewManager_init 함수를 호출하여 초기화해야 합니다.

void android_main(android_app* app) {
  app->onInputEvent = HandleInputEvent;

  ReviewErrorCode error_code = ReviewManager_init(app->activity->vm, app->activity->clazz);
  if (error_code == REVIEW_NO_ERROR) {
    // You can use the API.
  }
}

인앱 리뷰 흐름 요청

인앱 리뷰를 요청하는 시기에 관한 안내에 따라 앱의 사용자 플로우에서 적절한 지점을 결정하여 사용자에게 리뷰를 요청하는 메시지를 표시합니다(예: 사용자가 게임 레벨을 끝낼 때 표시되는 요약 화면을 닫은 후). 앱이 이러한 지점 중 하나에 가까워지면 ReviewManager_requestReviewFlow를 호출하여 앱에서 인앱 검토 흐름을 실행하는 데 필요한 정보를 비동기식으로 요청합니다. ReviewManager_getReviewStatus를 호출(예: 프레임당 한 번씩)하여 ReviewManager_requestReviewFlow 작업의 진행 상황을 모니터링합니다. 최대 몇 초 정도 걸릴 수 있으므로 인앱 검토 흐름을 표시하려는 시점에 앱이 도달하기 전에 이 프로세스를 시작해야 합니다.

ReviewErrorCode error_code = ReviewManager_requestReviewFlow();
if (error_code == REVIEW_NO_ERROR) {
    // The request has successfully started, check the status using
    // ReviewManager_getReviewStatus.
} else {
    // Error such as REVIEW_PLAY_STORE_NOT_FOUND indicating that the in-app
    // review isn't currently possible.
}

상태 처리 및 인앱 리뷰 흐름 실행

요청이 시작되거나 인앱 리뷰 흐름이 실행될 때마다 ReviewManager_getReviewStatus를 사용하여 상태를 확인할 수 있습니다. 이렇게 하면 API 상태에 따라 로직을 정의할 수 있습니다. 이렇게 하는 한 가지 방법은 다음 예와 같이 상태를 전역 변수로 유지하고 사용자가 특정 작업(예: 게임에서 '다음 레벨' 버튼 탭하기)을 실행할 때 상태가 REVIEW_REQUEST_FLOW_COMPLETED인지 확인하는 것입니다.

ReviewStatus status;
ReviewErrorCode error_code = ReviewManager_getReviewStatus(&status);
if (error_code != REVIEW_NO_ERROR) {
    // There was an error with the most recent operation.
    return;
}

switch (status) {
    case REVIEW_REQUEST_FLOW_PENDING:
        // Request is ongoing. The flow can't be launched yet.
        break;
    case REVIEW_REQUEST_FLOW_COMPLETED:
        // Request completed. The flow can be launched now.
        break;
    case REVIEW_LAUNCH_FLOW_PENDING:
        // The review flow is ongoing, meaning the dialog might be displayed.
        break;
    case REVIEW_LAUNCH_FLOW_COMPLETED:
        // The review flow has finished. Continue with your app flow (for
        // example, move to the next screen).
        break;
    default:
        // Unknown status.
        break;
}

상태가 REVIEW_REQUEST_FLOW_COMPLETED이고 앱이 준비되면 인앱 리뷰 흐름을 실행합니다.

// This call uses android_native_app_glue.h.
ReviewErrorCode error_code = ReviewManager_launchReviewFlow(app->activity->clazz);
if (error_code != REVIEW_NO_ERROR) {
    // There was an error while launching the flow.
    return;
}

인앱 리뷰 흐름을 실행한 후 완료 상태를 계속 확인하고 앱 흐름을 계속 진행합니다. 이 작업을 처리하는 일반적인 방법은 게임 루프 패턴을 따르는 것입니다.

리소스 확보

앱에서 API 사용을 완료하면(예: 인앱 리뷰 흐름이 완료된 후) ReviewManager_destroy 함수를 호출하여 리소스를 확보해야 합니다.

void ReviewManager_destroy();

다음 단계

앱의 인앱 검토 흐름 테스트를 통해 통합이 제대로 작동하는지 확인합니다.