Arcore-android-sdk: Unavailable AR Core Exception

Created on 17 Jan 2018  路  9Comments  路  Source: google-ar/arcore-android-sdk

Im trying to implement ARCore preview 2 into my application but whenever i build, i am getting a "_Please install ARCore_" message under the UnavailableArcoreNotInstalledException exception. Not sure if I'm missing anything in my gradle, or what i may have left out, can anyone help with this issue?

My gradle and main activity is below:

`apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.ar"
        minSdkVersion 24
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    buildToolsVersion '27.0.3'
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile project(':core-0.91.0')
    compile project(':obj-0.2.1')
}
`
`package com.ar;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.support.design.widget.BaseTransientBottomBar;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import com.google.ar.core.Anchor;
import com.google.ar.core.Camera;
import com.google.ar.core.Config;
import com.google.ar.core.Frame;
import com.google.ar.core.Plane;
import com.google.ar.core.PointCloud;
import com.google.ar.core.Session;
import com.google.ar.core.Trackable;
import com.google.ar.core.exceptions.UnavailableApkTooOldException;
import com.google.ar.core.exceptions.UnavailableArcoreNotInstalledException;
import com.google.ar.core.exceptions.UnavailableSdkTooOldException;
import com.usaa.emerge.autoar.rendering.BackgroundRenderer;
import com.usaa.emerge.autoar.rendering.PlaneRenderer;
import com.usaa.emerge.autoar.rendering.PointCloudRenderer;

import java.util.ArrayList;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class ARCameraActivity extends AppCompatActivity implements GLSurfaceView.Renderer {
    private static final String TAG = ARCameraActivity.class.getSimpleName();

    //Creates and initializes renderers.
    private GLSurfaceView mSurfaceView;

    private Session mSession;
    private GestureDetector mGestureDetector;
    private Snackbar mMessageSnackbar;
    private DisplayRotationHelper mDisplayRotationHelper;

    private final BackgroundRenderer mBackgroundRenderer = new BackgroundRenderer();
//    private final ObjectRenderer mVirtualObject = new ObjectRenderer();
//    private final ObjectRenderer mVirtualObjectShadow = new ObjectRenderer();
    private final PlaneRenderer mPlaneRenderer = new PlaneRenderer();
    private final PointCloudRenderer mPointCloud = new PointCloudRenderer();

    // Temporary matrix allocated here to reduce number of allocations for each frame.
    private final float[] mAnchorMatrix = new float[16];

    private final ArrayList<Anchor> mAnchors = new ArrayList<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ar_camera_layout);

        mSurfaceView = findViewById(R.id.surfaceview);
        mDisplayRotationHelper = new DisplayRotationHelper(this);

        //Set up tap listener
        mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                onSingleTapUp(e);
                return true;
            }

            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }
        });
        mSurfaceView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mGestureDetector.onTouchEvent(event);
            }
        });

        // Set up renderer.
        mSurfaceView.setPreserveEGLContextOnPause(true);
        mSurfaceView.setEGLContextClientVersion(2);
        mSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); // Alpha used for plane blending.
        mSurfaceView.setRenderer(this);
        mSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

        Exception exception = null;
        String message = null;
        try {
            mSession = new Session(this);
        } catch (UnavailableArcoreNotInstalledException e) {
            message = "Please install ARCore";
            exception = e;
        } catch (UnavailableApkTooOldException e) {
            message = "Please update ARCore";
            exception = e;
        } catch (UnavailableSdkTooOldException e) {
            message = "Please update this app";
            exception = e;
        } catch (Exception e) {
            message = "This device does not support AR";
            exception = e;
        }

        if (message != null) {
            showSnackbarMessage(message, true);
            Log.e(TAG, "Exception creating session", exception);
            return;
        }

        // Create default config and check if supported.
        Config config = new Config(mSession);
        if (!mSession.isSupported(config)) {
            showSnackbarMessage("This device does not support AR", true);
        }
        mSession.configure(config);
    }

    @Override
    protected void onResume() {
    super.onResume();

        // ARCore requires camera permissions to operate. If we did not yet obtain runtime
        // permission on Android M and above, now is a good time to ask the user for it.
        if (CameraPermissionHelper.hasCameraPermission(this)) {
            if (mSession != null) {
                showLoadingMessage();
                // Note that order matters - see the note in onPause(), the reverse applies here.
                mSession.resume();
            }
            mSurfaceView.onResume();
            mDisplayRotationHelper.onResume();
        } else {
            CameraPermissionHelper.requestCameraPermission(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Note that the order matters - GLSurfaceView is paused first so that it does not try
        // to query the session. If Session is paused before GLSurfaceView, GLSurfaceView may
        // still call mSession.update() and get a SessionPausedException.
        mDisplayRotationHelper.onPause();
        mSurfaceView.onPause();
        if (mSession != null) {
            mSession.pause();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        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();
        }
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            // Standard Android full-screen functionality.
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.1f, 0.1f, 0.1f, 1.0f);

        // Create the texture and pass it to ARCore session to be filled during update().
        mBackgroundRenderer.createOnGlThread(/*context=*/ this);
        if (mSession != null) {
            mSession.setCameraTextureName(mBackgroundRenderer.getTextureId());
        }

        mPointCloud.createOnGlThread(/*context=*/this);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        mDisplayRotationHelper.onSurfaceChanged(width, height);
        GLES20.glViewport(0, 0, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // Clear screen to notify driver it should not load any pixels from previous frame.
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        if (mSession == null) {
            return;
        }

        try {
            // Obtain the current frame from ARSession. When the configuration is set to
            // UpdateMode.BLOCKING (it is by default), this will throttle the rendering to the
            // camera framerate.
            Frame frame = mSession.update();
            Camera camera = frame.getCamera();

            // Draw background.
            mBackgroundRenderer.draw(frame);

            // If not tracking, don't draw 3d objects.
            if (camera.getTrackingState() == Trackable.TrackingState.PAUSED) {
                return;
            }

            // Get projection matrix.
            float[] projmtx = new float[16];
            camera.getProjectionMatrix(projmtx, 0, 0.1f, 100.0f);

            // Get camera matrix and draw.
            float[] viewmtx = new float[16];
            camera.getViewMatrix(viewmtx, 0);

            // Compute lighting from average intensity of the image.
            final float lightIntensity = frame.getLightEstimate().getPixelIntensity();

            // Visualize tracked points.
            PointCloud pointCloud = frame.acquirePointCloud();
            mPointCloud.update(pointCloud);
            mPointCloud.draw(viewmtx, projmtx);

            // Application is responsible for releasing the point cloud resources after
            // using it.
            pointCloud.release();

            // Check if we detected at least one plane. If so, hide the loading message.
            if (mMessageSnackbar != null) {
                for (Plane plane : mSession.getAllTrackables(Plane.class)) {
                    if (plane.getType() == com.google.ar.core.Plane.Type.HORIZONTAL_UPWARD_FACING
                            && plane.getTrackingState() == Trackable.TrackingState.TRACKING) {
                        hideLoadingMessage();
                        break;
                    }
                }
            }

            // Visualize planes.
            mPlaneRenderer.drawPlanes(
                    mSession.getAllTrackables(Plane.class), camera.getDisplayOrientedPose(), projmtx);

            // Visualize anchors created by touch.
            float scaleFactor = 1.0f;
            for (Anchor anchor : mAnchors) {
                if (anchor.getTrackingState() != Trackable.TrackingState.TRACKING) {
                    continue;
                }
                // Get the current pose of an Anchor in world space. The Anchor pose is updated
                // during calls to session.update() as ARCore refines its estimate of the world.
                anchor.getPose().toMatrix(mAnchorMatrix, 0);
            }
        } catch (Throwable t) {
            // Avoid crashing the application due to unhandled exceptions.
            Log.e(TAG, "Exception on the OpenGL thread", t);
        }
    }

    private void showSnackbarMessage(String message, boolean finishOnDismiss) {
        mMessageSnackbar = Snackbar.make(
                ARCameraActivity.this.findViewById(android.R.id.content),
                message, Snackbar.LENGTH_INDEFINITE);
        mMessageSnackbar.getView().setBackgroundColor(0xbf323232);
        if (finishOnDismiss) {
            mMessageSnackbar.setAction(
                    "Dismiss",
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mMessageSnackbar.dismiss();
                        }
                    });
            mMessageSnackbar.addCallback(
                    new BaseTransientBottomBar.BaseCallback<Snackbar>() {
                        @Override
                        public void onDismissed(Snackbar transientBottomBar, int event) {
                            super.onDismissed(transientBottomBar, event);
                            finish();
                        }
                    });
        }
        mMessageSnackbar.show();
    }

    private void showLoadingMessage() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                showSnackbarMessage("Searching for surfaces...", false);
            }
        });
    }

    private void hideLoadingMessage() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mMessageSnackbar != null) {
                    mMessageSnackbar.dismiss();
                }
                mMessageSnackbar = null;
            }
        });
    }
}
`



Most helpful comment

For someone that might land here while facing the same problem in the future - We have found that turning Android Studio's Instant Run Off seems to reliably fix this issue.

All 9 comments

Have you side-loaded the arcore APK? See here:

https://developers.google.com/ar/develop/java/getting-started#prepare-device

Yes, i forgot to mention that i have already side loaded the APK. Also when I run the preview 2 SDK from studio, that works fine on my device

Oh, interesting! I鈥檒l look into this. Could you provide a logcat from before launching to the exception being thrown?

@inio

`01-18 11:42:02.944 13863-13863/? I/zygote64: Late-enabling -Xcheck:jni
01-18 11:42:03.242 13863-13863/com.usaa.emerge.autoar I/InstantRun: starting instant run server: is main process
01-18 11:42:03.508 13863-13888/com.usaa.emerge.autoar D/OpenGLRenderer: HWUI GL Pipeline
01-18 11:42:03.551 13863-13888/com.usaa.emerge.autoar I/Adreno: QUALCOMM build                   : a2b520b, Ibdb59aaa19
                                                                Build Date                       : 09/05/17
                                                                OpenGL ES Shader Compiler Version: EV031.21.01.00
                                                                Local Branch                     : O15B
                                                                Remote Branch                    : 
                                                                Remote Branch                    : 
                                                                Reconstruct Branch               : 
01-18 11:42:03.576 13863-13888/com.usaa.emerge.autoar I/Adreno: PFP: 0x005ff087, ME: 0x005ff063
01-18 11:42:03.612 13863-13888/com.usaa.emerge.autoar I/zygote64: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
01-18 11:42:03.613 13863-13888/com.usaa.emerge.autoar I/OpenGLRenderer: Initialized EGL, version 1.4
01-18 11:42:03.613 13863-13888/com.usaa.emerge.autoar D/OpenGLRenderer: Swap behavior 2
01-18 11:42:14.268 13863-13863/com.usaa.emerge.autoar I/native: session_create.cc:24 Entering ArSession_create.
01-18 11:42:14.306 13863-13863/com.usaa.emerge.autoar E/DynamiteClient: Failed to load native library [packageName=com.google.ar.core,libraryName=arcore_c] from remote package:

                                                                        java.lang.IllegalStateException: java.lang.IllegalArgumentException: The concrete class implementing IObjectWrapper must have exactly *one* declared private field for the wrapped object.  Preferably, this is an instance of the ObjectWrapper<T> class.
                                                                            at com.google.vr.dynamite.LoadedInstanceCreator.newNativeLibraryLoader(PG:6)
                                                                            at akq.onTransact(PG:23)
                                                                            at android.os.Binder.transact(Binder.java:627)
                                                                            at com.google.android.aidl.BaseProxy.transactAndReadException(BaseProxy.java:45)
                                                                            at com.google.vr.dynamite.client.ILoadedInstanceCreator$Stub$Proxy.newNativeLibraryLoader(ILoadedInstanceCreator.java:67)
                                                                            at com.google.vr.dynamite.client.DynamiteClient.checkVersion(DynamiteClient.java:37)
                                                                            at com.google.ar.core.Session.nativeCreateSession(Native Method)
                                                                            at com.google.ar.core.Session.<init>(Session.java:87)
                                                                            at com.usaa.emerge.autoar.ARCameraActivity.onCreate(ARCameraActivity.java:97)
                                                                            at android.app.Activity.performCreate(Activity.java:7000)
                                                                            at android.app.Activity.performCreate(Activity.java:6991)
                                                                            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
                                                                            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
                                                                            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
                                                                            at android.app.ActivityThread.-wrap11(Unknown Source:0)
                                                                            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                            at android.os.Looper.loop(Looper.java:164)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:6494)
                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
                                                                         Caused by: java.lang.IllegalArgumentException: The concrete class implementing IObjectWrapper must have exactly *one* declared private field for the wrapped object.  Preferably, this is an instance of the ObjectWrapper<T> class.
                                                                            at com.google.vr.dynamite.client.ObjectWrapper.unwrap(PG:36)
                                                                            at com.google.vr.dynamite.LoadedInstanceCreator.newNativeLibraryLoader(PG:2)
                                                                            at akq.onTransact(PG:23)聽
                                                                            at android.os.Binder.transact(Binder.java:627)聽
                                                                            at com.google.android.aidl.BaseProxy.transactAndReadException(BaseProxy.java:45)聽
                                                                            at com.google.vr.dynamite.client.ILoadedInstanceCreator$Stub$Proxy.newNativeLibraryLoader(ILoadedInstanceCreator.java:67)聽
                                                                            at com.google.vr.dynamite.client.DynamiteClient.checkVersion(DynamiteClient.java:37)聽
                                                                            at com.google.ar.core.Session.nativeCreateSession(Native Method)聽
                                                                            at com.google.ar.core.Session.<init>(Session.java:87)聽
                                                                            at com.usaa.emerge.autoar.ARCameraActivity.onCreate(ARCameraActivity.java:97)聽
                                                                            at android.app.Activity.performCreate(Activity.java:7000)聽
                                                                            at android.app.Activity.performCreate(Activity.java:6991)聽
                                                                            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)聽
                                                                            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)聽
                                                                            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)聽
                                                                            at android.app.ActivityThread.-wrap11(Unknown Source:0)聽
                                                                            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)聽
                                                                            at android.os.Handler.dispatchMessage(Handler.java:106)聽
                                                                            at android.os.Looper.loop(Looper.java:164)聽
                                                                            at android.app.ActivityThread.main(ActivityThread.java:6494)聽
                                                                            at java.lang.reflect.Method.invoke(Native Method)聽
                                                                            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)聽
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)聽
01-18 11:42:14.306 13863-13863/com.usaa.emerge.autoar W/native: session_create.cc:36 ArSession_create returning AR_UNAVAILABLE_ARCORE_NOT_INSTALLED.
01-18 11:42:14.337 13863-13863/com.usaa.emerge.autoar E/ARCameraActivity: Exception creating session
                                                                          com.google.ar.core.exceptions.UnavailableArcoreNotInstalledException
                                                                              at com.google.ar.core.Session.throwExceptionFromArStatus(Session.java:343)
                                                                              at com.google.ar.core.Session.nativeCreateSession(Native Method)
                                                                              at com.google.ar.core.Session.<init>(Session.java:87)
                                                                              at com.usaa.emerge.autoar.ARCameraActivity.onCreate(ARCameraActivity.java:97)
                                                                              at android.app.Activity.performCreate(Activity.java:7000)
                                                                              at android.app.Activity.performCreate(Activity.java:6991)
                                                                              at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
                                                                              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
                                                                              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
                                                                              at android.app.ActivityThread.-wrap11(Unknown Source:0)
                                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
                                                                              at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                              at android.os.Looper.loop(Looper.java:164)
                                                                              at android.app.ActivityThread.main(ActivityThread.java:6494)
                                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                                              at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
01-18 11:42:14.641 13863-13868/com.usaa.emerge.autoar I/zygote64: Do partial code cache collection, code=22KB, data=29KB
01-18 11:42:14.641 13863-13868/com.usaa.emerge.autoar I/zygote64: After code cache collection, code=22KB, data=29KB
01-18 11:42:14.641 13863-13868/com.usaa.emerge.autoar I/zygote64: Increasing code cache capacity to 128KB`

@DeucedeDos Thanks, that'll help us track this down.

One thing I see suspicious is the compile project(':core-0.91.0') clause in the gradle file that I assume provides the ARCore AAR. What's going on in that build?

@inio Yes that build provides the ARCore AAR which I imported from the preview 2 SDK.

configurations.maybeCreate("default")
artifacts.add("default", file('core-0.91.0.aar'))

After some digging we're a little baffled by this one. Some things to try:

  1. Disable Proguard for both the AAR project and the main build (see #122)
  2. Replace the separate project for the AAR with a direct dependency.

Not sure exactly what fixed this, but i seems to be working fine now.

For someone that might land here while facing the same problem in the future - We have found that turning Android Studio's Instant Run Off seems to reliably fix this issue.

Was this page helpful?
0 / 5 - 0 ratings