启用 ARCore

本页介绍如何在您的 Android Studio 项目中启用 ARCore 功能。 为此,您需要做的是:

  1. 向 manifest 添加 AR 必备或 AR 可选条目
  2. 向您的项目添加构建依赖项
  3. 执行运行时检查以确保 ARCore 受支持和已安装,并且已获得摄像头权限

向 manifest 添加 AR 必备或 AR 可选条目

AR 应用有两种类型:AR 必备AR 可选

AR 可选应用

包含可选 AR 功能(这些功能仅在支持 ARCore 的设备上激活)的应用称为 AR 可选应用。

  • AR 可选应用可在不支持 ARCore 的设备上安装和运行。
  • 当用户安装 AR 可选应用时,应用商店不会随应用一起自动安装 ARCore

要将您的应用声明为 AR 可选,请修改 AndroidManifest.xml 以包含下列条目:

<!-- 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 必备应用

没有 AR 就无法使用的应用称为 AR 必备应用。

  • 应用商店只为支持 ARCore 的设备提供您的应用。
  • 当用户安装 AR 必备应用时,应用商店会自动安装 ARCore。 不过,您的应用仍必须执行额外的运行时检查,以防 ARCore 之后被卸载或需要更新版本的 ARCore。

如需了解详细信息,请参阅在应用商店中发布 AR 应用

要将您的应用声明为 AR 必备,请修改 AndroidManifest.xml 以包含下列条目:

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

添加构建依赖项

要将 ARCore 添加到您的 Android Studio 项目,请执行下列步骤:

  • 确保您的项目build.gradle 文件包括 Google 的 Maven 代码库:

    allprojects {
        repositories {
            google()
            …
    
  • 在您的应用build.gradle 文件中添加最新的 ARCore 库作为依赖项:

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

执行运行时检查

检查是否支持 ARCore(仅限 AR 可选应用)

AR 可选应用可以利用 ArCoreApk.checkAvailability() 来确定当前设备是否支持 ARCore。 在不支持 ARCore 的设备上,AR 可选应用应停用 AR 相关功能并隐藏关联的界面元素:

@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);
  }
}

请注意,checkAvailability() 可能需要查询网络资源来确定设备是否支持 ARCore。 在此期间,它将返回 UNKNOWN_CHECKING。 为缩短感知延迟时间和减少迸现,应用应在其生命周期早期调用一次 checkAvailability() 以启动查询,并忽略返回值。 这样一来,在调用 maybeEnableArButton() 时便可立即提供缓存的结果。

以下流程图说明了前面代码示例中的逻辑:

请求摄像头权限(AR 可选AR 必备应用)

在创建 AR 会话前,AR 可选AR 必备应用都必须确保已获得摄像头权限。 hello_ar_java 示例包含一个 CameraPermissionHelper 类,这个类可以复制到您的项目中,并且应当从您的 AR Activity 的 onResume() 函数中调用:

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

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

  …
}

HelloArActivity 中所示,您的 AR Activity 还必须实现 onRequestPermissionsResult(…)

@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();
  }
}

检查是否已安装 ARCore(AR 可选AR 必备应用)

在创建 ARCore 会话前,应用还必须调用 ArCoreApk.requestInstall() 来检查是否已安装兼容版本的 ARCore。 这将提示用户安装或更新 ARCore(如果需要)。

// 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.
  }
  …
}

以下流程图说明了前面代码示例中的逻辑:

如果 requestInstall() 返回 INSTALL_REQUESTED,则当前 Activity 将暂停,并提示用户安装或更新 ARCore:

当用户返回 Activity 后,Activity 的 onResume() 会再次执行。

后续步骤