Check for ARCore before launching a Unity module on Android.

Once you have integrated a Unity module in an Android app, you should add the following to make sure you’re not launching the module on devices that do not support ARCore. It also instructs users to install the ARCore app for devices that support it, but don’t have it yet.

Usage

if (activity.checkForARCore(true)) {
	// Launch the AR module.
}

(Note: launching a Unity module from Android is explained here.

build.gradle

Add the ARCore library to your non-AR main module as well.

dependencies {
	...
    // ARCore library
    implementation 'com.google.ar:core:1.4.0'
}

AndroidManifest.xml

<manifest>
	...
    <uses-feature
        android:name="android.hardware.camera.ar"
        android:required="false" />
    <application>
    	...
    	<meta-data
            android:name="com.google.ar.core"
            android:value="optional" />
    </application>

Use this method to show / hide the launch button

    private fun maybeEnableAR() {

        val availability = ArCoreApk.getInstance().checkAvailability(this)

        if (availability.isTransient) {
            // Re-query at 5Hz while we check compatibility.
            Handler().postDelayed({
                maybeEnableAR()
            }, 200)
        } else if (availability.isSupported) {
            // TODO show the UI that launches your AR module
        }
    }

Before launching the module, request camera permissions

The UnityPlayerActivity itself probably also does this itself, but the method checkForARCore also needs it and it runs before launching the module.

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        if (requestCode == REQUEST_AR) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                checkForARCore(false)
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

Finally, call this method before launching your module

(As instructed at the top of the post).

fun checkForARCore(requestCameraPermission: Boolean): Boolean {

    var hasPermission = checkSelfPermission(Manifest.permission.CAMERA)
    if (hasPermission != PackageManager.PERMISSION_GRANTED) {
        if (requestCameraPermission) {
            requestPermissions(arrayOf(Manifest.permission.CAMERA), REQUEST_AR)
        }
        return false
    }

    if (arSession != null) {
        return true
    } else {
        try {
            when (ArCoreApk.getInstance().requestInstall(this, userRequestedARCoreInstall)) {
                ArCoreApk.InstallStatus.INSTALLED -> {
                    arSession = Session(this)
                    return true
                }
                ArCoreApk.InstallStatus.INSTALL_REQUESTED -> {
                    // Ensures next invocation of requestInstall() will either return
                    // INSTALLED or throw an exception.
                    userRequestedARCoreInstall = false
                }
            }
        } catch (e: UnavailableUserDeclinedInstallationException) {
            // TODO Display an appropriate message to the user and return gracefully.
        }
    }
    return false
}