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;
}
});
}
}
`
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:
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.
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 RunOff seems to reliably fix this issue.