集成应用内评价(原生)

本指南介绍如何使用原生(C 或 C++)代码将应用内评价集成到您的应用中。如果您使用的是 Kotlin 或 Java 或者 Unity,请参阅单独的集成指南。

原生 SDK 概览

Play Core 原生 SDK 是 Google Play Core 库系列的一部分。Play Core 原生 SDK 包含一个 C 头文件 review.h,用于封装来自 Java Play 应用内评价库的 ReviewManager。此头文件允许您的应用直接从原生代码调用 API。如需简要了解可用的公共函数,请参阅 Play Review 原生模块文档

ReviewManager_requestReviewFlow 会启动一个请求,用于收集稍后启动应用内评价流程所需的信息。您可以使用 ReviewManager_getReviewStatus 跟踪请求的结果。如需详细了解 ReviewManager_getReviewStatus 可以返回的所有状态,请参阅 ReviewErrorCode

如果函数运行成功,则请求函数和启动函数都会返回 REVIEW_NO_ERROR

设置您的开发环境

下载 Play Core Native SDK

您必须先接受以下条款及条件才能下载。

条款及条件

上次修改时间:2020 年 9 月 24 日
  1. 使用 Play Core 软件开发套件,即表示您同意在遵守 Google API 服务条款(以下简称“API 服务条款”)的同时,也遵守这些条款。如果这些条款与《API 服务条款》存在冲突,请以这些条款为准。请仔细阅读这些条款和《API 服务条款》。
  2. 就这些条款而言,“API”是指 Google 的 API、其他开发者服务和相关软件(包括任何可再分发代码)。
  3. “可再分发代码”是指 Google 提供的调用 API 的对象代码或头文件。
  4. 根据这些条款和《API 服务条款》的规定,您只能在将可再分发代码纳入您的 API 客户端时对其进行复制和分发。Google 及其许可人拥有可再分发代码的所有权利、所有权和利益,包括任何及所有知识产权和其他专有权利。您不得修改、翻译可再分发代码,也不得创作可再分发代码的衍生作品。
  5. Google 随时可变更这些条款。如有变更,Google 会向您发出通知,同时您也可以选择不继续使用 Play Core 软件开发套件。Google 会在此网址 (https://developer.android.com/guide/playcore/license) 上发布条款修改通知。变更不具有追溯效力。
下载 Play Core Native SDK

play-core-native-sdk-1.13.0.zip

  1. 执行以下其中一项操作:

    • 安装 Android Studio 4.0 或更高版本。使用 SDK 管理器界面安装 Android SDK Platform 版本 10.0(API 级别 29)。
    • 安装 Android SDK 命令行工具,然后使用 sdkmanager 安装 Android SDK Platform 版本 10.0(API 级别 29)。
  2. 使用 SDK 管理器安装最新的 CMake 和 Android 原生开发套件 (NDK),让 Android Studio 做好原生开发准备。如需详细了解如何创建或导入原生项目,请参阅 NDK 入门指南

  3. 下载 zip 文件并将其解压缩到您的项目所在位置。

    下载链接 大小 SHA-256 校验和
    35.6 MiB 4eee8aafbe0309c0b4ba377c7c7bc1986c73ae70dd7ce3a04f792e1a67d79d51
  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.0.0'
            implementation 'com.google.android.play:asset-delivery:2.0.0'
            implementation 'com.google.android.play:integrity:1.0.1'
            implementation 'com.google.android.play:review:2.0.0'
    
            // 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.0.0")
        implementation("com.google.android.play:asset-delivery:2.0.0")
        implementation("com.google.android.play:integrity:1.0.1")
        implementation("com.google.android.play:review:2.0.0")
    
        // 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 原生 SDK 可能会收集版本相关数据,以便 Google 改进产品,包括:

  • 应用的软件包名称
  • 应用的软件包版本
  • Play Core 原生 SDK 的版本

当您将应用软件包上传到 Play 管理中心时,系统会收集这些数据。如需停用此数据收集流程,请移除 build.gradle 文件中的 $playcoreDir/playcore-native-metadata.jar 导入项。

请注意,这种与使用 Play Core 原生 SDK 相关的数据收集行为以及 Google 使用所收集数据的行为,与您将应用软件包上传至 Play 管理中心时 Google 收集在 Gradle 中声明的库依赖项无关且相互独立。

将 Play Core 原生 SDK 集成到您的项目后,请在包含 API 调用的文件中添加下面这行代码:

添加 review.h

将 Play Core 原生 SDK 集成到您的项目中之后,请在将包含 API 调用的文件中添加以下代码行:

#include "play/review.h"

初始化 Review API

每当您要使用该 API 时,都必须先调用 ReviewManager_init 函数来对其进行初始化,如下面使用 android_native_app_glue.h 构建的示例所示:

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();

后续步骤

测试应用的应用内评价流程,以验证您的集成是否正常运行。