Enable ARCore

This page describes how to enable ARCore functionality in your Android NDK projects. To do this, you need to:

Add AR Required or AR Optional to manifest

There are two types of AR apps: AR Required and AR Optional.

AR Required

AR Required means that your app is not usable without AR and makes your app available only on devices that support ARCore. For more information, see Publishing AR Apps in the Play Store.

To make your app AR Required, modify your app manifest to include the following entries:

<uses-sdk android:minSdkVersion="{24 or higher}" />

  ...
  <uses-feature android:name="android.hardware.camera.ar" android:required="true" />

  <application>
    ...
        <meta-data android:name="com.google.ar.core" android:value="required" />
    ...

AR Optional

AR Optional means that your app includes one or more AR features that are activated if the device supports ARCore. But the app can be installed and run on devices that don't support ARCore. When users install an AR Optional app, the Play Store does not install ARCore.

To tag your app as AR Optional, modify your app manifest to include the following entries:

  <uses-sdk android:minSdkVersion="{14 or higher}" />
  ...

  <application>
    ...
        <meta-data android:name="com.google.ar.core" android:value="optional" />
    ...

Add build dependencies

To add the ARCore library to your Android Studio project, perform these steps:

  1. Make sure your project's build.gradle file includes Google's Maven repository.

    allprojects {
    repositories {
        google()
            ...
    
  2. Extract native libraries from ARCore aar.

    The native libraries are included in the ARCore aar file. In order to use them as part of a C/C++ project, they must be extracted from the archive so they can be referenced directly. To do this, add a custom task to your module's build.gradle file (e.g. app/build.gradle).

    The header file for ARCore, arcore_c_api.h is included in the GitHub SDK project:

    Define a variable to a directory in the app/build directory. The native libraries will be extracted to this directory. Also create a gradle configuration to hold the extraction tasks and data.

    /*
    The arcore aar library contains the native shared libraries.  These 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 }
    
    

    Create a task to copy the native libraries from the aar file, and add it to the build dependencies

      // Extracts the shared libraries from aars in the natives configuration.
      // This is done 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)
          }
      }
    
  3. Configure the native build flags to pass the locations to the external build tools.

    This example is from the samples in the GitHub project.

          externalNativeBuild {
              cmake {
                  cppFlags "-std=c++11", "-Wall"
                  arguments "-DANDROID_STL=c++_static",
                          "-DARCORE_LIBPATH=${arcore_libpath}/jni",
                          "-DARCORE_INCLUDE=${project.rootDir}/../../libraries/include"
              }
          }
    

  4. Add the dependencies for both the Java and the native libraries.

     dependencies {
          ...
          // Add java and native dependencies on the ARCore library
          implementation 'com.google.ar:core:1.5.0'
          natives 'com.google.ar:core:1.5.0'
          ...
     }
    
  5. Reference the native libraries in 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}
    )
    

Perform runtime checks

Check whether ARCore is installed

All AR apps must call ArCoreApk_requestInstall() before creating an ARCore session. ArCoreApk_requestInstall() checks whether a compatible version of ARCore is installed (it might be out of date or have been manually removed by the user) and will prompt the user to install ARCore if it is not present.

// Tracks if we have already triggered an installation request.
bool install_requested_;

void nativeOnCreate() {
  // other setup

  install_requested_ = false;
}

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

    ArInstallStatus install_status;
    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:
        install_requested_ = true;
        return;
    }

    // Request camera permissions.

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

    // Configure session
  }

  // Normal onResume behavior
}

If ArCoreApk_requestInstall() returns AR_INSTALL_STATUS_INSTALL_REQUESTED, the current activity pauses and the user is prompted to install or update ARCore. The activity's onResume() executes again when the user returns to the activity.

Check whether ARCore is supported (AR Optional only)

AR optional apps can use ArCoreApk_checkAvailability() to determine if the current device supports ARCore. On a device that does not support ARCore, apps should disable AR-related functionality and hide associated UI elements.

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/enable AR button.
  } else {
    // Hide/disable AR button.
  }
}

Then, when the user wants to use an AR feature, your app should ensure that ARCore is installed. An easy way to do this is by launching an activity that follows the AR Required pattern described above.

Next steps

Read the code and comments in the sample app, as well as the C API Reference.

Send feedback about...