ARCore 中文文档 下载 App

Android iOS 跨平台 Cloud Anchors 共享

Cloud Anchors 的跨平台设计

Cloud Anchors 是 Google 少数几个真跨平台的 AR 能力之一——同一个 anchorId 可以在 Android 和 iOS 之间自由传递。这个设计的好处是:你在 Android 上开发的 Cloud Anchor 应用,iOS 用户可以无缝加入共享。

但跨平台共享不是没有限制——不同平台的实现细节有差异。

跨平台共享的前提条件

要让 Android 和 iOS 设备能共享同一个 Cloud Anchor,必须满足:

条件说明
同一个 Google Cloud 项目两端的 Cloud Anchors API Key 必须来自同一个 GCP 项目
同一版本的 API尽量用 ARCore 1.20+(Android)和 ARCore iOS SDK 6.0+(iOS),旧版本可能不兼容
相似的 ARCore 版本托管端和解析端的 ARCore 版本差距不要太大
支持 Cloud Anchors 的设备两端都得是支持 Cloud Anchors 的设备(绝大多数 ARCore 设备都支持)

跨平台工作流

Android 设备(托管)                iOS 设备(解析)
──────────────────────────────────────────────────────────
创建本地 Anchor
session.hostCloudAnchor(anchor)
上传特征点地图到 Google Cloud
                 ← 返回 anchorId

分享 anchorId(微信/二维码/服务器)
                 ↓
                 iOS 收到 anchorId
                 [GARSession resolveCloudAnchor:anchorId]
                 下载特征点地图 + 摄像头画面匹配
                 ← 返回 iOS 端可以用的 GARAnchor
                 在 iOS 坐标系下渲染同一个虚拟物体

Android → iOS 的 API Key 配置

在 Android Studio 中配置 Cloud Anchors API Key:

// AndroidManifest.xml
<meta-data
    android:name="com.google.android.ar.API_KEY"
    android:value="YOUR_ANDROID_API_KEY" />

在 iOS Xcode 中配置:

<!-- Info.plist -->
<key>GARAPIKey</key>
<string>YOUR_IOS_API_KEY</string>

两个 API Key 必须来自同一个 Google Cloud 项目,且分别在 GCP Console 中绑定了对应平台(Android 绑定应用包名,iOS 绑定 Bundle ID)。

跨平台共享的精度差异

Android 和 iOS 的 Cloud Anchors 使用相同的特征点匹配算法,但设备硬件差异可能影响精度:

差异点AndroidiOS影响
摄像头分辨率因设备而异相对统一高端 Android 和 iPhone 基本一致
IMU 精度各厂商不同苹果统一校准iPhone 上 SLAM 通常更稳定
Cloud Anchors 算法版本ARCore SDK 版本决定ARCore iOS SDK 版本决定差距不要超过主版本

实际测试中,同一 anchorId 在 Android 和 iOS 上解析后的 Anchor 位置通常能精确到几厘米范围内——完全够多人共享体验。

Unity 跨平台 Cloud Anchors

Unity AR Foundation + Cloud Anchors Extensions 可以同时支持 Android 和 iOS:

// 代码里不需要区分 Android/iOS,统一用 ARCloudAnchorManager
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class CloudAnchorExample : MonoBehaviour
{
    private ARCloudAnchorManager cloudAnchorManager;
    private ARAnchor anchor;

    void Start()
    {
        cloudAnchorManager = GetComponent<ARCloudAnchorManager>();
    }

    // 托管
    public void HostAnchor(Pose pose)
    {
        anchor = anchorManager.AddAnchor(pose);
        var request = cloudAnchorManager.HostAnchor(anchor, TimeSpan.FromDays(7));
        request.completed += OnHostCompleted;
    }

    void OnHostCompleted(ARHostCloudAnchorResult result)
    {
        if (result.status == ARHostCloudAnchorResult.AnchorHostedStatus.Hosted)
        {
            string anchorId = result.cloudAnchorId;
            // 分享给其他设备
        }
    }

    // 解析
    public void ResolveAnchor(string anchorId)
    {
        var request = cloudAnchorManager.ResolveAnchor(anchorId);
        request.completed += OnResolveCompleted;
    }

    void OnResolveCompleted(ARResolveCloudAnchorResult result)
    {
        if (result.status == ARResolveCloudAnchorResult.AnchorResolveStatus.Resolved)
        {
            // result.anchor 就是解析好的 Cloud Anchor
        }
    }
}

Unity 底层会自动调用对应平台的 Cloud Anchors API——Android 走 ARCore Cloud Anchors,iOS 走 ARCore iOS SDK 的 Cloud Anchors。

iOS 上的特别注意事项

Info.plist 权限声明

iOS 使用 Cloud Anchors 需要额外声明:

<!-- 摄像头权限(必须) -->
<key>NSCameraUsageDescription</key>
<string>使用摄像头来创建和共享增强现实体验</string>

<!-- 相册权限(可选,如果要保存共享内容) -->
<key>NSPhotoLibraryUsageDescription</key>
<string>保存您的增强现实作品</string>

Cloud Anchors 在 iOS 上的局限性

iOS 版 ARCore Cloud Anchors 有少量功能缺失(相比 Android):

如果你的应用强依赖某些 Cloud Anchors 高级功能,需要分别在两个平台上做功能检测和降级。

跨平台共享的典型用例

用例描述
多人 AR 绘画一群朋友在同一房间里,各自用手机在同一张桌子上画 3D 涂鸦。Cloud Anchors 保证每个人看到的画都来自所有人的共同创作
AR 室内设计协作设计师在现场用 Android 手机把虚拟家具放在客户的客厅里,然后把 anchorId 发给客户的 iPhone,让客户在自己家里看效果
位置打卡用户在某个景点打卡放一个 AR 虚拟徽章,徽章用 Cloud Anchor 锚定位置。其他任何走到该景点的人(Android 或 iOS)用你的应用都能看到这个徽章
AR 营销活动品牌商在某个商场的特定位置放限时 AR 内容(比如虚拟优惠券),任何走到该位置的消费者用手机就能触发

安全考虑

Cloud Anchors 没有内建的访问控制——任何知道 anchorId 的设备都能托管或解析。如果你的应用有以下需求,需要自己在应用层加安全机制:

需求方案
防止他人恶意覆盖/删除 Cloud Anchor在托管端记录 anchorId 到你的服务器,只允许创建者本人修改
防止未授权用户解析 Cloud Anchor把 anchorId 作为私密信息(如二维码 + 一次性 Token)传递,而不是公开分享
Cloud Anchor 生命周期管理在服务器上跟踪所有 anchorId 和 TTL,到期前通知创建者重新托管