You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复创建Anchor时出现的AR_ERROR_NOT_TRACKING错误

解决AR Core创建Anchor时的AR_ERROR_NOT_TRACKING崩溃问题

嘿,我一眼就看出问题所在了——你在onCreate方法里直接调用session.createAnchor(),这时候AR Core的相机跟踪还没准备好呢!

AR Core启动后需要先完成环境检测、初始化跟踪状态,这个过程不是瞬间完成的。在onCreate阶段,Session刚被初始化,相机还没开始正常跟踪,这时候强行创建Anchor肯定会触发AR_ERROR_NOT_TRACKING错误。

下面是具体的修复方案和修改后的代码:

核心修复思路

  • 不要在Activity初始化阶段创建Anchor:onCreate是Activity启动的早期阶段,AR SceneView还没进入渲染循环,跟踪状态根本没稳定下来。
  • 监听跟踪状态,等待合适时机:通过AR SceneView的帧回调,等到相机跟踪状态变为TrackingState.TRACKING时,再执行创建Anchor的操作。
  • 确保模型渲染器加载完成:避免因为markerRenderable还没加载好导致空指针。

修改后的完整代码

private ArFragment fragment;
private Session mSession;
private ModelRenderable markerRenderable;
// 标记是否已创建Anchor,避免重复执行
private boolean anchorCreated = false;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (!checkIsSupportedDeviceOrFinish(this)){
        return;
    }
    setContentView(R.layout.activity_navigation);
    fragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.sceneform_fragment);
    
    // 初始化Session
    if (mSession == null){
        try {
            mSession = new Session(this);
            fragment.getArSceneView().setupSession(mSession);
        } catch (UnavailableArcoreNotInstalledException | UnavailableApkTooOldException | UnavailableSdkTooOldException | UnavailableDeviceNotCompatibleException e) {
            e.printStackTrace();
        }
    }

    // 异步加载模型渲染器
    ModelRenderable.builder()
            .setSource(this, Uri.parse("marker.sfb"))
            .build()
            .thenAccept(renderable -> markerRenderable = renderable)
            .exceptionally( throwable -> {
                Toast toast = Toast.makeText(this, "Unable to load marker renderable", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
                return null;
            });

    // 设置场景更新监听器,在每帧更新时检查跟踪状态
    fragment.getArSceneView().getScene().addOnUpdateListener(frameTime -> {
        Frame frame = fragment.getArSceneView().getArFrame();
        // 跳过无效帧或模型未加载完成的情况
        if (frame == null || markerRenderable == null || anchorCreated) {
            return;
        }

        // 检查相机当前的跟踪状态
        TrackingState trackingState = frame.getCamera().getTrackingState();
        if (trackingState == TrackingState.TRACKING) {
            // 跟踪状态稳定,创建Anchor
            createFixedPositionAnchor();
            anchorCreated = true;
        }
    });
}

private void createFixedPositionAnchor() {
    Session session = fragment.getArSceneView().getSession();
    if (session == null) {
        Toast.makeText(this, "AR Session not available", Toast.LENGTH_SHORT).show();
        return;
    }

    float[] position = { 0, 0, (float)-0.75}; // 距离相机75cm的位置
    float[] rotation = { 0, 0, 0, 1 };
    try {
        Anchor anchor = session.createAnchor(new Pose(position, rotation));
        AnchorNode anchorNode = new AnchorNode(anchor);
        anchorNode.setRenderable(markerRenderable);
        anchorNode.setParent(fragment.getArSceneView().getScene());
    } catch (NotTrackingException e) {
        // 保险起见捕获异常,避免崩溃
        e.printStackTrace();
        Toast.makeText(this, "Failed to create anchor: Camera not tracking", Toast.LENGTH_SHORT).show();
    }
}

关键修改点说明

  • 把创建Anchor的逻辑移到了addOnUpdateListener的帧回调中,确保只有在相机跟踪状态稳定时才执行。
  • 增加了anchorCreated布尔标记,防止每帧都尝试创建Anchor,避免重复操作。
  • 在创建Anchor前先检查markerRenderable是否加载完成,避免空指针异常。
  • 捕获了NotTrackingException,即使跟踪状态判断有误差,也不会直接崩溃应用。

额外注意事项

  • AR Core的跟踪状态稳定需要几秒时间,启动后不要着急创建Anchor。
  • 如果是要创建地理位置相关的Anchor,还需要确保设备位置服务开启,且AR Core版本在1.20以上(支持地理定位Anchor)。
  • 所有AR相关的操作(如创建Anchor、操作Session)都必须在主线程执行,不要在子线程中调用。

内容的提问来源于stack exchange,提问作者ZQ.O

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:22:42