无法成功托管云锚并无法从Google Cloud Anchor API检索云锚ID

时间:2019-02-21 23:01:42

标签: android arcore sceneform

我正在尝试在Google Arcore Cloud API上托管云锚。我已在清单中包含api密钥。我还可以看到当我要托管锚点时android设备发出的请求,并且从api发送回了响应,如下图所示。

Api Reads and Writes

但是,即使我已经设置了更新侦听器,云锚状态也永远不会更改为SUCCESS,并且我也从未收到过来自Google的云锚ID,如下所示。通过调试程序,我可以看到AppAnchorState从未从NONE更改过,但是我没有设法收集任何其他信息。

我同时使用Sceneform和Arcore 1.7.0。下面是我用来尝试托管锚点并从api返回云锚点ID的代码。

在此阶段我一直在努力解决这个问题,因此能提供任何帮助将不胜感激。

public class ArActivity extends AppCompatActivity {

    private enum AppAnchorState {
        NONE,
        HOSTING,
        HOSTED,
        RESOLVING,
        RESOLVED
    }

    private AppAnchorState appAnchorState = AppAnchorState.NONE;

    private static final String TAG = ArActivity.class.getSimpleName();
    private static final double MIN_OPENGL_VERSION = 3.0;
    private static final String GLTF_ASSET = "https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/Duck/glTF/Duck.gltf";

    private ArFragment arFragment;
    private ModelRenderable renderable;
    private SnackbarHelper snackbarHelper;
    private Anchor cloudAnchor;

    @Override
    @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"})
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!checkIsSupportedDeviceOrFinish(this)) {
            return;
        }

        snackbarHelper = new SnackbarHelper();

        setContentView(R.layout.activity_ux);
        arFragment = (CustomArFragment) getSupportFragmentManager().findFragmentById(R.id.sceneform_fragment);
        arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame);

        ModelRenderable.builder()
                .setSource(this, RenderableSource.builder().setSource(
                        this,
                        Uri.parse(GLTF_ASSET),
                        RenderableSource.SourceType.GLTF2)
                        .build())
                .setRegistryId(GLTF_ASSET)
                .build()
                .thenAccept(renderable -> this.renderable = renderable)
                .exceptionally(
                        throwable -> {
                            Toast toast =
                                    Toast.makeText(this, "Unable to load renderable " +
                                            GLTF_ASSET, Toast.LENGTH_LONG);
                            toast.setGravity(Gravity.CENTER, 0, 0);
                            toast.show();
                            return null;
                        });

        Button clearButton = findViewById(R.id.clear_button);
        clearButton.setOnClickListener(view -> setCloudAnchor(null));

        Button hostButton = findViewById(R.id.host_button);
        hostButton.setOnClickListener(view -> hostModel());

        arFragment.setOnTapArPlaneListener(
            (HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
                if (renderable == null) {
                    return;
                }

                // Create the Anchor.
                Anchor anchor = hitResult.createAnchor();
                setCloudAnchor(anchor);

                AnchorNode anchorNode = new AnchorNode(cloudAnchor);
                TransformableNode node = new TransformableNode(arFragment.getTransformationSystem());
                node.setRenderable(renderable);
                node.setParent(anchorNode);
                arFragment.getArSceneView().getScene().addChild(anchorNode);
                node.select();
            });
    }

    private void hostModel() {
        if (cloudAnchor != null) {
            arFragment.getArSceneView().getSession().hostCloudAnchor(cloudAnchor);
            appAnchorState = AppAnchorState.HOSTING;
            snackbarHelper.showMessage(this, "Now hosting anchor...");
        } else {
            snackbarHelper.showMessage(this, "No anchor to host, Please create an anchor...");
        }
    }

    private void setCloudAnchor (Anchor newAnchor){
        if (cloudAnchor != null){
            cloudAnchor.detach();
        }

        cloudAnchor = newAnchor;
        appAnchorState = AppAnchorState.NONE;
        snackbarHelper.hide(this);
    }

    private void onUpdateFrame(FrameTime frameTime){
        checkUpdatedAnchor();
    }

    private synchronized void checkUpdatedAnchor(){
        if (appAnchorState != AppAnchorState.HOSTING){
            return;
        }
        Anchor.CloudAnchorState cloudState = cloudAnchor.getCloudAnchorState();
        if (appAnchorState == AppAnchorState.HOSTING) {
            if (cloudState.isError()) {
                snackbarHelper.showMessageWithDismiss(this, "Error hosting anchor.. "
                        + cloudState);
                appAnchorState = AppAnchorState.NONE;
            } else if (cloudState == Anchor.CloudAnchorState.SUCCESS) {
                snackbarHelper.showMessageWithDismiss(this, "Anchor hosted with id "
                        + cloudAnchor.getCloudAnchorId());
                appAnchorState = AppAnchorState.HOSTED;
            }
        }
    }

    public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) {
        String openGlVersionString =
                ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE))
                        .getDeviceConfigurationInfo()
                        .getGlEsVersion();
        if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) {
            Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later");
            Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG)
                    .show();
            activity.finish();
            return false;
        }
        return true;
    }
}
public class CustomArFragment extends ArFragment {

    @Override
    protected Config getSessionConfiguration(Session session) {
        Config config = super.getSessionConfiguration(session);
        config.setCloudAnchorMode(Config.CloudAnchorMode.ENABLED);
        return config;
    }

}

0 个答案:

没有答案