在 Android NDK 应用中启用 AR

启用 AR,即可在新应用或现有应用中使用增强现实功能。

将应用配置为 AR 必备或 AR 可选

为了节省单台设备的空间,所有 AR 功能都会存储在一款名为面向 AR 的 Google Play 服务的应用中,该应用将通过 Play 商店单独更新。使用 AR 功能的 Android 应用会通过 ARCore SDK 与面向 AR 的 Google Play 服务通信。您可以通过以下两种方式配置支持 AR 功能的应用:AR 必备AR 可选。此标识决定了应用如何与“面向 AR 的 Google Play 服务”应用交互。

如果没有 ARCore,AR 必备应用将无法运行。它需要支持 ARCore 的设备且已安装“面向 AR 的 Google Play 服务”。

  • Google Play 商店将只在支持 ARCore 的设备上提供 AR 必备应用。
  • 当用户安装 AR 必备应用时,Google Play 商店会自动在其设备上安装“面向 AR 的 Google Play 服务”。不过,如果“面向 AR 的 Google Play 服务”已过时或已被手动卸载,您的应用仍必须执行其他运行时检查

AR 可选应用使用 ARCore 增强现有功能。它具有可选的 AR 功能,这些功能仅在已安装“面向 AR 的 Google Play 服务”且支持 ARCore 的设备上才能激活。

  • AR 可选应用可在不支持 ARCore 的设备上安装和运行。
  • 当用户安装 AR 可选应用时,Google Play 商店不会自动在设备上安装面向 AR 的 Google Play 服务。
AR 要求AR 可选
AR 功能使用情况 您的应用需要 ARCore 才能实现基本功能。 ARCore 可以增强应用的功能。您的应用可以在没有 ARCore 支持的情况下运行。
Play 商店公开范围 您的应用只会在支持 ARCore 的设备上的 Play 商店中上架。 您的应用遵循常规的列出程序
面向 AR 的 Google Play 服务安装方法 Play 商店会随应用一起安装“面向 AR 的 Google Play 服务”。 您的应用使用了 ArCoreApk.requestInstall() 下载并安装 ARCore。
Android minSdkVersion 要求 Android 7.0(API 级别 24) Android 4.4(API 级别 19),尽管运行任何 AR 功能至少需要 Android 7.0(API 级别 24)
必须使用 ArCoreApk_checkAvailability()ArCoreApk_checkAvailabilityAsync() 检查 ARCore 支持和安装状态
必须使用 ArCoreApk.requestInstall() 安装“面向 AR 的 Google Play 服务”

如需将您的应用设为 AR 必备或 AR 可选,请更新您的 AndroidManifest.xml,在其中添加以下条目:

AR 要求

<uses-permission android:name="android.permission.CAMERA" />

<!-- Limits app visibility in the Google Play Store to ARCore supported devices
     (https://developers.google.com/ar/devices). -->
<uses-feature android:name="android.hardware.camera.ar" />

<application …>
    …

    <!-- "AR Required" app, requires "Google Play Services for AR" (ARCore)
         to be installed, as the app does not include any non-AR features. -->
    <meta-data android:name="com.google.ar.core" android:value="required" />
</application>

AR 可选

<uses-permission android:name="android.permission.CAMERA" />

<!-- If your app was previously AR Required, don't forget to remove the
     `<uses-feature android:name="android.hardware.camera.ar" />` entry, as
     this would limit app visibility in the Google Play Store to only
     ARCore supported devices. -->

<application …>
    …

    <!-- "AR Optional" app, contains non-AR features that can be used when
         "Google Play Services for AR" (ARCore) is not available. -->
    <meta-data android:name="com.google.ar.core" android:value="optional" />
</application>

然后,修改应用的 build.gradle,以指定 minSdkVersion 至少为 24

 android {
     defaultConfig {
         …
         minSdkVersion 24
     }
 }

添加 build 依赖项

  1. 确保项目的 build.gradle 文件包含 Google 的 Maven 制品库。

    allprojects {
        repositories {
            google()
            …
        }
    }
    
  2. 将自定义任务添加到模块的 build.gradle 文件中,以从 ARCore AAR 文件中提取包含的原生库。这样,您可以直接在 C 或 C++ 项目中引用它们。

  3. app/build 目录中,定义一个变量,指定原生库将解压缩到的目录。

  4. 创建 Gradle 配置以保存数据和提取任务。

    /*
    The ARCore AAR library contains native shared libraries that are
    extracted before building to a temporary directory.
    */
    def arcore_libpath = "${buildDir}/arcore-native"
    
    // Create a configuration to mark which aars to extract .so files from
    configurations { natives }
    
  5. 创建从 AAR 文件中复制原生库的任务,并将其添加到 build 依赖项。

    // Extracts the shared libraries from AARs in the native configuration
    // so that NDK builds can access these libraries.
    task extractNativeLibraries() {
       // Extract every time.
       outputs.upToDateWhen { false }
    
       doFirst {
            configurations.natives.files.each { f ->
                copy {
                    from zipTree(f)
                    into arcore_libpath
                    include "jni/**/*"
                }
            }
        }
    }
    
    tasks.whenTaskAdded {
        task-> if (task.name.contains("external") && !task.name.contains("Clean")) {
            task.dependsOn(extractNativeLibraries)
        }
    }
    
  6. 配置原生构建标志,以将位置传递给外部构建工具。

    // From the sample app.
    externalNativeBuild {
        cmake {
            cppFlags "-std=c++11", "-Wall"
            arguments "-DANDROID_STL=c++_static",
                    "-DARCORE_LIBPATH=${arcore_libpath}/jni",
                    "-DARCORE_INCLUDE=${project.rootDir}/../../libraries/include"
        }
    }
    
  7. 添加 Java 库和原生库的依赖项。

    dependencies {
         ...
         // Add Java and native dependencies to the ARCore library.
         implementation 'com.google.ar:core:1.33.0'
         natives 'com.google.ar:core:1.33.0'
         ...
    }
    
  8. CMakeLists.txt 中引用原生库。

    # Import the ARCore library.
    add_library(arcore SHARED IMPORTED)
    set_target_properties(arcore PROPERTIES IMPORTED_LOCATION
                  ${ARCORE_LIBPATH}/${ANDROID_ABI}/libarcore_sdk_c.so
                  INTERFACE_INCLUDE_DIRECTORIES ${ARCORE_INCLUDE}
    )
    

执行运行时检查

在运行时,请执行以下操作,以确保应用中的 AR 功能顺畅运行。

检查是否支持 ARCore

AR 必备应用和 AR 可选应用都应使用 ArCoreApk_checkAvailability()ArCoreApk_checkAvailabilityAsync() 来确定当前设备是否支持 ARCore。在不支持 ARCore 的设备上,应用应停用 AR 相关功能并隐藏关联的界面元素。

Android NDK 应用可以使用 Java ArCoreApk检查兼容性并管理原生 C ARCore Session API 中的安装。根据应用的结构,这可能比使用 ArCoreApk_ 函数更简单,因为这涉及到大量错误处理和界面互动。

void maybeEnableArButton(JNIEnv env, jobject context) {
  // Likely called from Activity.onCreate() of an activity with AR buttons.
  ArAvailability availability
  ArCoreApk_checkAvailability(env, context, &availability);
  if (availability == AR_AVAILABILITY_UNKNOWN_CHECKING) {
    // Set a timer to call maybeEnableArButton() again after about 200ms.
  }
  if (availability == AR_AVAILABILITY_SUPPORTED_NOT_INSTALLED ||
      availability == AR_AVAILABILITY_SUPPORTED_APK_TOO_OLD ||
      availability == AR_AVAILABILITY_SUPPORTED_INSTALLED) {
    // Show or enable the AR button.
  } else {
    // Hide or disable the AR button.
  }
}
即使“面向 AR 的 Google Play 服务”是与您的 AR 必备应用一起安装的,使用不受支持的设备的用户也可能会通过外部来源安装此应用。使用 ArCoreApk_checkAvailability()ArCoreApk_checkAvailabilityAsync() 检查是否支持 ARCore 可确保提供一致的体验。

ArCoreApk_checkAvailability() 可能需要查询网络资源来确定设备是否支持 ARCore。在此期间,它将返回 AR_AVAILABILITY_UNKNOWN_CHECKING。为了缩短感知延迟时间和减少弹入,应用应在其生命周期早期调用一次 ArCoreApk_checkAvailability() 来启动查询,并忽略返回值。这样一来,在可能显示进入 AR 的界面元素时,便可立即提供缓存的结果。

检查是否已安装“面向 AR 的 Google Play 服务”

AR 必备应用和 AR 可选应用都必须使用 ArCoreApk.requestInstall() ,检查是否(仍然)安装了面向 AR 的 Google Play 服务的兼容版本,并确保已下载所有必需的 ARCore 设备配置文件数据。

// Tracks if an installation request has already been triggered.
bool install_requested_;

void nativeOnCreate() {
  // Do other setup here.

  install_requested_ = false;
}

void nativeOnResume(JNIEnv env, jobject activity) {
  if (ar_session_ == null) {
    bool user_requested_install = !install_requested_;

    ArInstallStatus install_status;
    // Ensure that Google Play Services for AR and ARCore device profile data are
    // installed and up to date.
    ArStatus error = ArCoreApk_requestInstall(
        env, activity, user_requested_install, &install_status);
    if (error != AR_SUCCESS) {
      // Inform user of error.
      return;
    }

    switch (install_status) {
      case AR_INSTALL_STATUS_INSTALLED:
        break;
      case AR_INSTALL_STATUS_INSTALL_REQUESTED:
        // When this method returns AR_INSTALL_STATUS_INSTALL_REQUESTED:
        // 1. This activity will be paused.
        // 2. The user is prompted to install or update Google Play
        //    Services for AR (market://details?id=com.google.ar.core).
        // 3. ARCore downloads the latest device profile data.
        // 4. This activity is resumed. The next invocation of
        //    ArCoreApk_requestInstall() will either return
        //    AR_INSTALL_STATUS_INSTALLED or throw an exception if the
        //    installation or update did not succeed.
        install_requested_ = true;
        return;
    }

    // Request camera permissions.

    error = ArSession_create(env, context, &ar_session_);
    if (error != AR_SUCCESS) {
      // Inform user of error.
      return;
    }

    // Configure the ARCore session.
  }

  // Normal onResume behavior.
}

遵守用户隐私要求

若要在 Play 商店中发布您的应用,请确保您的应用符合 ARCore 的 用户隐私要求

后续步骤