如果我理解的话,一旦ARCore 1.0将在Google Play上发布,就必须在设备上安装它才能运行ARCore应用。
如何检查设备上是否安装了ARCore lib / apk?
答案 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
。