Google is committed to advancing racial equity for Black communities. See how.

Enable ARCore

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

  1. Choose between AR Required and AR Optional for your app
  2. Add AR Required or AR Optional entries to your app's manifest
  3. Add build dependencies to your project
  4. Perform runtime checks to ensure that:
    • The device supports ARCore,
    • Google Play Services for AR is installed on it,
    • The camera permission has been granted.
  5. Make sure that your app complies with ARCore's User Privacy Requirements

Choosing between AR Required or AR Optional

An app that supports AR features can be configured in two ways: AR Required and AR Optional.

An AR Required app cannot function without ARCore. 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.

An AR Optional app uses ARCore to augment a different functionality. 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.

AR RequiredAR Optional
AR Feature usage Your app needs ARCore for basic functionality. ARCore augments your app's functionality. Your app can run without ARCore support.
Play Store visibility Your app is only listed in the Play Store on devices with ARCore support. Your app follows normal listing procedures.
Google Play Services for AR installation method The Play Store installs Google Play Services for AR alongside your app. Your app uses ArCoreApk.requestInstall() to download and install ARCore.
Android minSdkVersion requirements Android 7.0 (API Level 24) Android 4.0 (API Level 14)
Must use ArCoreApk.checkAvailability() to check ARCore support and install status
Must use ArCoreApk.requestInstall() to install Google Play Services for AR

For more information, see Publishing AR Apps in the Google Play Store.

Adding entries to your app's manifest

Modify your AndroidManifest.xml to include the following entries:

AR Required

<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 Optional

<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, ensure that your app has at least the required minSdkVersion in your app's build.gradle:

AR Required

android {
    defaultConfig {
        …
        minSdkVersion 24
    }
}

AR Optional

android {
    defaultConfig {
        …
        minSdkVersion 14
    }
}

Add build dependencies

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

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

    allprojects {
        repositories {
            google()
            …
        }
    }
    
  • Add the latest ARCore library as a dependency in your app's build.gradle file:

    dependencies {
        …
        implementation 'com.google.ar:core:1.24.0'
    }
    

Perform runtime checks

Check whether ARCore is supported

Both AR Required and AR Optional apps should use ArCoreApk.checkAvailability() to determine if the current device supports ARCore. On devices that do not support ARCore, apps should disable AR related functionality and hide associated UI elements.

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  // Enable AR-related functionality on ARCore supported devices only.
  maybeEnableArButton();
  …
}

void maybeEnableArButton() {
  ArCoreApk.Availability availability = ArCoreApk.getInstance().checkAvailability(this);
  if (availability.isTransient()) {
    // Continue to query availability at 5Hz while compatibility is checked in the background.
    new Handler().postDelayed(new Runnable() {
      @Override
      public void run() {
        maybeEnableArButton();
      }
    }, 200);
  }
  if (availability.isSupported()) {
    mArButton.setVisibility(View.VISIBLE);
    mArButton.setEnabled(true);
  } else { // The device is unsupported or unknown.
    mArButton.setVisibility(View.INVISIBLE);
    mArButton.setEnabled(false);
  }
}

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)

  // Enable AR-related functionality on ARCore supported devices only.
  maybeEnableArButton()
  …
}

fun maybeEnableArButton() {
  val availability = ArCoreApk.getInstance().checkAvailability(this)
  if (availability.isTransient) {
    // Continue to query availability at 5Hz while compatibility is checked in the background.
    Handler().postDelayed({
      maybeEnableArButton()
    }, 200)
  }
  if (availability.isSupported) {
    mArButton.visibility = View.VISIBLE
    mArButton.isEnabled = true
  } else { // The device is unsupported or unknown.
    mArButton.visibility = View.INVISIBLE
    mArButton.isEnabled = false
  }
}

Even though Google Play Services for AR is installed alongside your AR Required app, users with unsupported devices might install it from an external source. Using checkAvailability() to check for ARCore support ensures a consistent experience.

checkAvailability() may need to query network resources to determine whether the device supports ARCore. During this time, it will return UNKNOWN_CHECKING. To reduce the perceived latency and pop-in, apps should call checkAvailability() once early in its life cycle to initiate the query, ignoring the returned value. This way a cached result will be available immediately when maybeEnableArButton() is called.

Request camera permission

Both AR Optional and AR Required apps must ensure that the camera permission has been granted before creating an AR Session. The hello_ar_java sample includes a CameraPermissionHelper class which can be copied into your project and called from your AR activity's onResume() method:

Java

@Override
protected void onResume() {
  super.onResume();

  // ARCore requires camera permission to operate.
  if (!CameraPermissionHelper.hasCameraPermission(this)) {
    CameraPermissionHelper.requestCameraPermission(this);
    return;
  }

  …
}

Kotlin

override fun onResume() {
  super.onResume()

  // ARCore requires camera permission to operate.
  if (!CameraPermissionHelper.hasCameraPermission(this)) {
    CameraPermissionHelper.requestCameraPermission(this)
    return
  }

  …
}

Your AR activity must also implement onRequestPermissionsResult(), as seen in HelloArActivity:

Java

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] results) {
  super.onRequestPermissionsResult(requestCode, permissions, results);
  if (!CameraPermissionHelper.hasCameraPermission(this)) {
    Toast.makeText(this, "Camera permission is needed to run this application", Toast.LENGTH_LONG)
        .show();
    if (!CameraPermissionHelper.shouldShowRequestPermissionRationale(this)) {
      // Permission denied with checking "Do not ask again".
      CameraPermissionHelper.launchPermissionSettings(this);
    }
    finish();
  }
}

Kotlin

override fun onRequestPermissionsResult(
  requestCode: Int,
  permissions: Array<String>,
  results: IntArray
) {
  super.onRequestPermissionsResult(requestCode, permissions, results)
  if (!CameraPermissionHelper.hasCameraPermission(this)) {
    Toast.makeText(this, "Camera permission is needed to run this application", Toast.LENGTH_LONG)
      .show()
    if (!CameraPermissionHelper.shouldShowRequestPermissionRationale(this)) {
      // Permission denied with checking "Do not ask again".
      CameraPermissionHelper.launchPermissionSettings(this)
    }
    finish()
  }
}

Check whether Google Play Services for AR is installed

To check whether a compatible version of Google Play Services for AR is (still) installed, and to ensure that all required ARCore device profile data has been downloaded, both AR Required and AR Optional apps must call ArCoreApk.requestInstall() before creating an ARCore session. This prompts the user to install or update ARCore if needed, and ensures that required ARCore device profile data is downloaded.

Java

// requestInstall(Activity, true) will triggers installation of
// Google Play Services for AR if necessary.
private boolean mUserRequestedInstall = true;

@Override
protected void onResume() {
  super.onResume();

  // Check camera permission.
  …

  // Ensure that Google Play Services for AR and ARCore device profile data are
  // installed and up to date.
  try {
    if (mSession == null) {
      switch (ArCoreApk.getInstance().requestInstall(this, mUserRequestedInstall)) {
        case INSTALLED:
          // Success: Safe to create the AR session.
          mSession = new Session(this);
          break;
        case INSTALL_REQUESTED:
          // When this method returns `INSTALL_REQUESTED`:
          // 1. ARCore pauses this activity.
          // 2. ARCore prompts the user 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. ARCore resumes this activity. The next invocation of
          //    requestInstall() will either return `INSTALLED` or throw an
          //    exception if the installation or update did not succeed.
          mUserRequestedInstall = false;
          return;
      }
    }
  } catch (UnavailableUserDeclinedInstallationException e) {
    // Display an appropriate message to the user and return gracefully.
    Toast.makeText(this, "TODO: handle exception " + e, Toast.LENGTH_LONG)
        .show();
    return;
  } catch (…) {
    …
    return;  // mSession remains null, since session creation has failed.
  }
  …
}

Kotlin

// requestInstall(Activity, true) will triggers installation of
// Google Play Services for AR if necessary.
var mUserRequestedInstall = true

override fun onResume() {
  super.onResume()

  // Check camera permission.
  …

  // Ensure that Google Play Services for AR and ARCore device profile data are
  // installed and up to date.
  try {
    if (mSession == null) {
      when (ArCoreApk.getInstance().requestInstall(this, mUserRequestedInstall)) {
        ArCoreApk.InstallStatus.INSTALLED -> {
          // Success: Safe to create the AR session.
          mSession = Session(this)
        }
        ArCoreApk.InstallStatus.INSTALL_REQUESTED -> {
          // When this method returns `INSTALL_REQUESTED`:
          // 1. ARCore pauses this activity.
          // 2. ARCore prompts the user 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. ARCore resumes this activity. The next invocation of
          //    requestInstall() will either return `INSTALLED` or throw an
          //    exception if the installation or update did not succeed.
          mUserRequestedInstall = false
          return
        }
      }
    }
  } catch (e: UnavailableUserDeclinedInstallationException) {
    // Display an appropriate message to the user and return gracefully.
    Toast.makeText(this, "TODO: handle exception " + e, Toast.LENGTH_LONG)
        .show()
    return
  } catch (…) {
    …
    return  // mSession remains null, since session creation has failed.
  }
  …
}

Compliance with User Privacy Requirements

Make sure your app complies with ARCore's User Privacy Requirements.

Next steps