在 Android 应用中启用 AR

2024-07-06

启用 AR 即可在新应用或现有应用中使用增强现实功能。

将应用配置为“AR 必需”或“AR 可选”

为了节省各个设备上的空间,所有 AR 功能都存储在一个名为 Google Play Services for AR 的应用中,该应用由 Play 商店单独更新。使用 AR 功能的 Android 应用使用 ARCore SDK 与 Google Play 服务 AR 版进行通信。支持 AR 功能的应用可以通过以下两种方式进行配置:AR 必需和 AR 可选。此指定决定了应用与 Google Play 服务(面向 AR)应用的互动方式。

如果应用标记为必须使用 AR,则必须使用 ARCore 才能正常运行。它需要一部已安装“面向 AR 的 Google Play 服务”的受 ARCore 支持的设备。

Google Play 商店只会在支持 ARCore 的设备上提供 AR 必需应用。

当用户安装需要 AR 的应用时,Google Play 商店会自动在其设备上安装“面向 AR 的 Google Play 服务”。不过,您的应用仍必须执行额外的运行时检查,以防 Google Play 地图 AR 服务已过时或已被手动卸载。

AR 可选应用使用 ARCore 来增强现有功能。它具有可选的 AR 功能,这些功能仅在已安装面向 AR 的 Google Play 服务且支持 ARCore 的设备上启用。

不支持 ARCore 的设备可以安装和运行 AR 可选应用。

当用户安装 AR 可选应用时,Google Play 商店不会在设备上自动安装面向 AR 的 Google Play 服务。

必须使用 ARAR 可选

AR 功能使用情况

您的应用需要 ARCore 才能实现基本功能。

ARCore 可增强应用的功能。您的应用无需 ARCore 支持即可运行。

Play 商店公开范围

您的应用仅在支持 ARCore 的设备上在 Play 商店中上架。

您的应用遵循正常的商品详情提交流程。

“面向 AR 的 Google Play 服务”安装方法

Play 商店会随您的应用一起安装“面向 AR 的 Google Play 服务”。

您的应用使用

ArCoreApk.requestInstall()

下载并安装 ARCore。

Android minSdkVersion 要求

Android 7.0(API 级别 24)

Android 4.4(API 级别 19),但运行任何 AR 功能至少需要 Android 7.0(API 级别 24)

必须使用 ArCoreApk.checkAvailability() 或 ArCoreApk.checkAvailabilityAsync() 检查 ARCore 支持和安装状态

check_circle

check_circle

必须使用

ArCoreApk.requestInstall()

安装“面向 AR 的 Google Play 服务”

check_circle

check_circle

如需将应用设为 AR 必需或 AR 可选,请更新 AndroidManifest.xml 以包含以下条目:

必须使用 AR

AR 可选

然后,修改应用的 build.gradle,将 minSdkVersion 指定为至少 24:

android {

defaultConfig {

minSdkVersion 24

}

}

添加 build 依赖项

如需将 ARCore 添加到 Android Studio 项目,请执行以下操作:

确保项目的 build.gradle 文件包含 Google 的 Maven 代码库。

allprojects {

repositories {

google()

}

}

将最新的 ARCore 库作为依赖项添加到应用的 build.gradle 文件中。

dependencies {

implementation 'com.google.ar:core:1.33.0'

}

执行运行时检查

在运行时,请执行以下操作,以确保应用中的 AR 功能顺利运行。

检查是否支持 ARCore

无论是 AR 必需应用还是 AR 可选应用,都应使用 ArCoreApk.checkAvailability() 或 ArCoreApk.checkAvailabilityAsync() 来确定当前设备是否支持 ARCore。在不支持 ARCore 的设备上,应用应停用 AR 相关功能并隐藏关联的界面元素。

Kotlinoverride fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

// Enable AR-related functionality on ARCore supported devices only.

maybeEnableArButton()

}

fun maybeEnableArButton() {

ArCoreApk.getInstance().checkAvailabilityAsync(this) { availability ->

if (availability.isSupported) {

mArButton.visibility = View.VISIBLE

mArButton.isEnabled = true

} else { // The device is unsupported or unknown.

mArButton.visibility = View.INVISIBLE

mArButton.isEnabled = false

}

}

}

Java@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Enable AR-related functionality on ARCore supported devices only.

maybeEnableArButton();

}

void maybeEnableArButton() {

ArCoreApk.getInstance().checkAvailabilityAsync(this, availability -> {

if (availability.isSupported()) {

mArButton.setVisibility(View.VISIBLE);

mArButton.setEnabled(true);

} else { // The device is unsupported or unknown.

mArButton.setVisibility(View.INVISIBLE);

mArButton.setEnabled(false);

}

});

}

即使“面向 AR 的 Google Play 服务”与您的“必须支持 AR”应用一起安装,使用不受支持的设备的用户也可能会从外部来源安装该服务。使用 ArCoreApk.checkAvailability() 或 ArCoreApk.checkAvailabilityAsync() 检查 ARCore 支持情况可确保提供一致的体验。

ArCoreApk.checkAvailability() 可能需要查询网络资源,以确定设备是否支持 ARCore。在此期间,它会返回 UNKNOWN_CHECKING。为了减少感知延迟时间和弹出式窗口,应用应在其生命周期的早期调用 ArCoreApk.checkAvailability() 一次,以发起查询,并忽略返回的值。这样,当系统可能显示 AR 进入界面元素时,系统会立即提供缓存的结果。

检查是否已安装“面向 AR 的 Google Play 服务”

无论是 AR 必需应用还是 AR 可选应用,都必须先使用

ArCoreApk.requestInstall()

创建 ARCore 会话,以检查是否(仍)安装了兼容版本的 Google Play 服务(面向 AR),并确保已下载所有必需的 ARCore 设备配置数据。

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.

}

}

Java// requestInstall(Activity, true) will trigger 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.

}

}

请求相机权限

无论是 AR 可选应用还是 AR 必需应用,都必须先确保已授予相机权限,然后才能创建 AR 会话。

Kotlinoverride fun onResume() {

super.onResume()

// ARCore requires camera permission to operate.

if (!CameraPermissionHelper.hasCameraPermission(this)) {

CameraPermissionHelper.requestCameraPermission(this)

return

}

}

Java@Override

protected void onResume() {

super.onResume();

// ARCore requires camera permission to operate.

if (!CameraPermissionHelper.hasCameraPermission(this)) {

CameraPermissionHelper.requestCameraPermission(this);

return;

}

}

您的 AR activity 还必须实现 onRequestPermissionsResult()。

Kotlinoverride fun onRequestPermissionsResult(

requestCode: Int,

permissions: Array,

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()

}

}

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

}

}

遵守用户隐私权要求

如需在 Play 商店中发布应用,请确保您的应用符合 ARCore 的用户隐私权要求。

后续步骤

了解如何配置 ARCore 会话。