如何检查设备上是否安装了ARCore lib / apk?

时间:2018-01-31 15:07:25

标签: java android arcore

如果我理解的话,一旦ARCore 1.0将在Google Play上发布,就必须在设备上安装它才能运行ARCore应用。

如何检查设备上是否安装了ARCore lib / apk?

4 个答案:

答案 0 :(得分:2)

应该足以做类似的事情:

    try {
        arCoreSession = Session(this)

        val config = Config(arCoreSession)
        if (!arCoreSession.isSupported(config)) {
            Logger.d("ARCore not installed")
        } else {
            arCoreSession.configure(config)
        }
    } catch (ex: Throwable) {
        Logger.d("ARCore not installed")
    }

这就是我在这里使用的一款应用程序,并且可以在有或者没有ARCore的设备上正常工作。

答案 1 :(得分:2)

根据ARCore documentation 1.4.0,如果可选,则重要的是递归检查其可用性,然后安装它:

void maybeEnableArButton() {
  // Likely called from Activity.onCreate() of an activity with AR buttons.
  ArCoreApk.Availability availability = ArCoreApk.getInstance().checkAvailability(this);
  if (availability.isTransient()) {
    // re-query at 5Hz while we check compatibility.
    new Handler().postDelayed(new Runnable() {
      @Override
      public void run() {
        maybeEnableArButton();
      }
    }, 200);
  }
  if (availability.isSupported()) {
    mArButton.setVisibility(View.VISIBLE);
    mArButton.setEnabled(true);
    // indicator on the button.
  } else { // unsupported or unknown
    mArButton.setVisibility(View.INVISIBLE);
    mArButton.setEnabled(false);
  }
}

如果已经支持,只需检查是否已安装ARCore:

// Set to true ensures requestInstall() triggers installation if necessary.
private boolean mUserRequestedInstall = true;

// in onResume:
try {
  if (mSession == null) {
    switch (ArCoreApk.getInstance().requestInstall(this, mUserRequestedInstall)) {
      case INSTALLED:
        mSession = new Session(this);
        // Success.
        break;
      case INSTALL_REQUESTED:
        // Ensures next invocation of requestInstall() will either return
        // INSTALLED or throw an exception.
        mUserRequestedInstall = false;
        return;
    }
  }
} catch (UnavailableUserDeclinedInstallationException e) {
  // Display an appropriate message to the user and return gracefully.
  return;
} catch (...) {  // current catch statements
  ...
  return;  // mSession is still null
}

答案 2 :(得分:1)

有时,使用Rx方法更容易提出此要求。这是代码:

private fun getArAvailabilityRx(context: Context): Single<ArCoreApk.Availability> {
    return Single.fromCallable<ArCoreApk.Availability> {
        ArCoreApk.getInstance().checkAvailability(context)
    }.flatMap { availability ->
        if (availability.isTransient) {
            // `isTransient` means it hasn't finished loading value; let's request the value in 500 ms
            getArAvailabilityRx(context).delaySubscription(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
        } else {
            Single.just(availability)
        }
    }.observeOn(AndroidSchedulers.mainThread())
}

答案 3 :(得分:0)

这是我编写的一个小实用程序类(最初基于 https://github.com/google/helloargdx 中的一些内容)。

它将执行所有必要的检查和设置,以确保启动 Session 是安全的。

abstract class ArCheckFragment : Fragment() {

    private var userRequestedInstall = true

    abstract fun onCameraPermissionDeny()

    abstract fun onArCoreUnavailable(availability: Availability)

    abstract fun onArCoreInstallFail(exception: UnavailableException)

    abstract fun onArCoreInstallSuccess()

    override fun onResume() {
        super.onResume()
        performCheck()
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE_CAMERA_PERMISSION) {
            for (i in permissions.indices) {
                if (permissions[i] == Manifest.permission.CAMERA &&
                    grantResults[i] == PackageManager.PERMISSION_GRANTED
                ) {
                    checkArCore()
                    return
                }
            }
            onCameraPermissionDeny()
        }
    }

    /**
     * Performs the whole check
     */
    fun performCheck() {
        if (requestCameraPermission()) {
            checkArCore()
        }
    }

    /**
     * Requests the camera permission, if necessary.
     * @return whether camera permission is already granted. If so, the permission won't be requested.
     */
    private fun requestCameraPermission(): Boolean {
        if (ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            return true
        }
        requestPermissions(arrayOf(Manifest.permission.CAMERA), REQUEST_CODE_CAMERA_PERMISSION)
        return false
    }

    private fun checkArCore() {
        if (!isResumed) {
            return
        }
        val availability = ArCoreApk.getInstance().checkAvailability(activity)
        if (availability.isTransient) {
            requireView().postDelayed(AR_CORE_CHECK_INTERVAL) { checkArCore() }
            return
        }
        when (availability) {
            Availability.SUPPORTED_INSTALLED ->
                onArCoreInstallSuccess()
            Availability.SUPPORTED_APK_TOO_OLD,
            Availability.SUPPORTED_NOT_INSTALLED ->
                startArCoreInstallation()
            else ->
                onArCoreUnavailable(availability)
        }
    }

    private fun startArCoreInstallation() {
        try {
            val installStatus =
                ArCoreApk.getInstance().requestInstall(activity, userRequestedInstall)
            when (installStatus) {
                InstallStatus.INSTALLED -> onArCoreInstallSuccess()
                InstallStatus.INSTALL_REQUESTED,
                null ->
                    // Ensures next invocation of requestInstall() will either return
                    // INSTALLED or throw an exception.
                    userRequestedInstall = false
            }
        } catch (exception: UnavailableException) {
            onArCoreInstallFail(exception)
        }
    }

    companion object {
        private const val REQUEST_CODE_CAMERA_PERMISSION = 1
        private const val AR_CORE_CHECK_INTERVAL = 200L
    }
}

你可以子类化这个 Fragment 并实现抽象函数来接收关于这些检查结果的回调。只有在 onArCoreInstallSuccess 中才能安全地创建 Session