Enable ARCore

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

  1. Add AR Required or AR Optional entries to the manifest
  2. Add build dependencies to your project
  3. Perform runtime checks to ensure ARCore is supported and installed, and the camera permission has been granted

Add AR Required or AR Optional entries to manifest

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

AR Optional apps

Apps that include optional AR features that are only actviated on devices that support ARCore are referred to as AR Optional apps.

  • AR Optional apps can be installed and run on devices that don't support ARCore.
  • When users install an AR Optional app, the Play Store will not automatically install ARCore with the app.

To declare your app to be AR Optional, modify your AndroidManifest.xml to include the following entries:

<!-- AR Optional apps must declare minSdkVersion ≥ 14 -->
<uses-sdk android:minSdkVersion="14" />

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

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

AR Required apps

Apps that are not usable without AR are referred to as AR Required apps.

  • The Play Store makes your app available only on devices that support ARCore.
  • When users install an AR Required app, the Play Store automatically installs ARCore. However, your app must still perform additional runtime checks in case ARCore is later uninstalled or an updated version of ARCore is required.

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

To declare your app to be AR Required, modify your AndroidManifest.xml to include the following entries:

<!-- AR Required apps must declare minSdkVersion ≥ 24 -->
<uses-sdk android:minSdkVersion="24" />

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
…

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

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.4.0'
    }
    

Perform runtime checks

Check whether ARCore is supported (AR Optional apps only)

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

@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()) {
    // Re-query 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);
    // indicator on the button.
  } else { // Unsupported or unknown.
    mArButton.setVisibility(View.INVISIBLE);
    mArButton.setEnabled(false);
  }
}

Note, 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 it's life cycle to initiate the query, ignoring the returned value. This way a cached result will be available immediately when maybeEnableArButton() is called.

This flowchart illustrates the logic in the preceding code sample:

Request camera permission (AR Optional and AR Required apps)

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 should be called from your AR activity's onResume() method:

@Override
protected void 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:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] 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 ARCore is installed (AR Optional and AR Required apps)

Apps must also call ArCoreApk.requestInstall() before creating an ARCore session, to check whether a compatible version of ARCore is installed. This will prompt the user to install or update ARCore if needed.

// Set to true ensures requestInstall() triggers installation if necessary.
private boolean mUserRequestedInstall = true;

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

  // Check camera permission.
  …

  // Make sure ARCore is installed and up to date.
  try {
    if (mSession == null) {
      switch (ArCoreApk.getInstance().requestInstall(this, mUserRequestedInstall)) {
        case INSTALLED:
          // Success, create the AR session.
          mSession = new Session(this);
          break;
        case INSTALL_REQUESTED:
          // Ensures next invocation of requestInstall() will either return
          // INSTALLED or throw an exception.
          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 (…) {  // Current catch statements.
    …
    return;  // mSession is still null.
  }
  …
}

This flowchart illustrates the logic in the preceding code sample:

If requestInstall() returns INSTALL_REQUESTED, the current activity pauses and the user is prompted to install or update ARCore:

The activity's onResume() executes again once the user returns to the activity.

Next steps

Read the code and comments in the hello_ar_java sample, as well as the Java API Reference.

Send feedback about...