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 the manifest
- Add build dependencies to your project
- Perform runtime checks to ensure the device is ARCore-supported and that Google Play Services for AR is installed on it
- Make sure your app complies with ARCore's User Privacy Requirements
Google Play Services for AR
ARCore SDKs make AR features available on ARCore supported devices that have Google Play Services for AR (ARCore) installed.
Google Play Services for AR is automatically installed and kept up to date on the vast majority of supported devices.
Before starting an AR session, apps must:
- Check that ARCore is supported, by calling
ArCoreApk_checkAvailability
. - Check that Google Play Services for AR is installed and up to date, and that
required ARCore device profile data has been downloaded, by calling
ArCoreApk_requestInstall
.
Add AR Required or AR Optional to the manifest
An app that supports AR features can be configured in two ways: AR Required and AR Optional.
AR Required
To be usable, an AR Required app requires an ARCore Supported Device that has Google Play Services for AR installed on it.
The Google Play Store makes AR Required apps available only on devices that support ARCore.
When users install an AR Required app, the Google Play Store automatically installs Google Play Services for AR. However, your app must still perform additional runtime checks in case Google Play Services for AR must be updated or has been manually uninstalled.
For more information, see Publishing AR Apps in the Google Play Store.
To declare your app to be AR Required, modify your AndroidManifest.xml
to
include the following entries:
<uses-permission android:name="android.permission.CAMERA"/>
<!-- Limits app visibility in the Google Play Store to ARCore supported devices
(https://developers.google.com/ar/discover/supported-devices). -->
<uses-feature android:name="android.hardware.camera.ar" android:required="true"/>
<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>
Then, modify your app's build.gradle
to specify a minSdkVersion
of at least 24:
android {
defaultConfig {
…
minSdkVersion 24
}
}
AR Optional
An AR Optional app has optional AR features, which are activated only on ARCore supported devices that have Google Play Services for AR installed.
AR Optional apps can be installed and run on devices that don't support ARCore.
When users install an AR Optional app, the Google Play Store will not automatically install Google Play Services for AR with the app.
To declare your app to be AR Optional, modify your AndroidManifest.xml
to
include the following entries:
<uses-permission android:name="android.permission.CAMERA" />
<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>
Then, modify your app's build.gradle
to specify a minSdkVersion
of at least 14:
android {
defaultConfig {
…
minSdkVersion 14
}
}
Add build dependencies
To add the ARCore library to your Android Studio project, perform these steps:
Make sure your project's
build.gradle
file includes Google's Maven repository.allprojects { repositories { google() ...
Extract native libraries from ARCore aar.
The native libraries are included in the ARCore aar file. 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 (for example,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) } }
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" } }
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.23.0' natives 'com.google.ar:core:1.23.0' ... }
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
Google Play Services for AR is installed (it might be out of date or have been
manually removed by the user) and will prompt the user to install the service 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; // Ensure 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 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 the
service. 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 Google Play Services for AR is installed. An easy way to do this is by launching an activity that follows the AR Required pattern described above.
Compliance with User Privacy Requirements
Make sure your app complies with ARCore's User Privacy Requirements.
Next steps
Read the code and comments in the sample app, as well as the C API Reference.