Невозможно успешно разместить якоря облака и получить идентификатор якоря облака из API привязки облака Google

0

Я пытаюсь разместить облачный якорь на Google Arcore Cloud API. Я включил ключ api в свой манифест. Я также вижу запрос, который делает устройство Android, когда я хочу разместить якорь, и также есть ответ, отправляемый обратно из api, как показано на изображении ниже.

Api читает и записывает

Однако состояние привязки облака никогда не меняется на УСПЕХ, и я никогда не получаю идентификатор привязки облака от Google, хотя я настроил для этого прослушиватель обновлений, как показано ниже. Отлаживая программу, я вижу, что AppAnchorState никогда не меняется с NONE, но мне не удалось собрать никакой другой информации.

Я использую как сцену, так и arcore 1.7.0. Ниже приведен код, который я использую, чтобы попытаться разместить свой якорь и получить идентификатор облачного якоря обратно из api.

Любая помощь будет принята с благодарностью, так как я часами борюсь с проблемой на этом этапе.

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

}
1
  • Извинения @Zoe спасибо за совет 22 фев '19 в 8: 442019-02-22 11:44
1

Итак, я понял, в чем была моя проблема. Я не настраивал якорь облака, чтобы отслеживать изменения с сервера. Вот почему я мог видеть активность в API Google, но на устройстве ничего не происходило.

Все, что мне нужно было сделать, это изменить этот фрагмент кода:

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...");
        }
    }

и установите cloudAnchor для прослушивания изменений:

private void hostModel() {
        if (cloudAnchor != null) {
            cloudAnchor = 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...");
        }
    }