Интеграция ARCore в Android-приложение
ARCore работает на 400+ моделях Android-устройств — и это главная сложность. На Pixel 7 с тензорным чипом tracking держится стабильно. На бюджетном Redmi с той же версией ARCore — плоскости не обнаруживаются из-за слабой камеры и вибрации от дешёвого OIS. Тестировать на одном устройстве и считать, что работает везде — ошибка.
Совместимость и деградация
ARCore поддерживается только на устройствах из официального списка Google. Перед запуском сессии — обязательная проверка:
val availability = ArCoreApk.getInstance().checkAvailability(context)
when (availability) {
ArCoreApk.Availability.SUPPORTED_INSTALLED -> startArSession()
ArCoreApk.Availability.SUPPORTED_NOT_INSTALLED -> promptInstall()
ArCoreApk.Availability.UNSUPPORTED_DEVICE_NOT_CAPABLE -> showFallback()
else -> { /* SUPPORTED_APK_TOO_OLD, UNKNOWN_ERROR */ }
}
UNSUPPORTED_DEVICE_NOT_CAPABLE — устройство никогда не получит поддержку. Показываем fallback, не пытаемся устанавливать ARCore. Нет смысла биться об эту стену.
Архитектура AR-сессии
ARCore в Android-приложении строится вокруг Session объекта из com.google.ar.core. Интеграция с рендерингом — через GLSurfaceView (старый путь) или ArSceneView из Sceneform (deprecated Google, но форк maintained). Для новых проектов берём SceneView — активно поддерживаемый форк Sceneform с Kotlin coroutines API.
// build.gradle
implementation("io.github.sceneview:arsceneview:2.0.3")
val arSceneView = binding.arSceneView
arSceneView.onSessionCreated = { session ->
session.configure(
Config(session).apply {
planeFindingMode = Config.PlaneFindingMode.HORIZONTAL_AND_VERTICAL
lightEstimationMode = Config.LightEstimationMode.ENVIRONMENTAL_HDR
depthMode = Config.DepthMode.AUTOMATIC
}
)
}
ENVIRONMENTAL_HDR — ключевой флаг для реалистичного освещения. ARCore захватывает HDR-кубическую карту окружения и применяет к PBR-материалам. Объект получает тени и отражения из реальной сцены.
Depth API
На устройствах с depth-сенсором (ToF-камера: Pixel 6 Pro, Samsung S21 Ultra) DepthMode.AUTOMATIC включает реальную карту глубины. На остальных — ARCore генерирует depth через ML-модель по одной камере. Окклюзия реальными объектами:
arSceneView.onSessionUpdated = { session, frame ->
if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {
val depthImage = frame.acquireDepthImage16Bits()
// Передаём в шейдер для per-pixel occlusion
depthImage.close()
}
}
Не забывать .close() — Image объекты из ARCore держат native memory, утечка ведёт к OutOfMemoryError в течение минуты активной сессии.
Plane detection и hit test
Размещение объекта по тапу — стандартный кейс:
arSceneView.onGestureListener = object : DefaultARSceneViewGestureListener(arSceneView) {
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
val hitResults = arSceneView.frame?.hitTest(e.x, e.y) ?: return false
val hitResult = hitResults.firstOrNull { hit ->
hit.trackable is Plane && (hit.trackable as Plane).isPoseInPolygon(hit.hitPose)
} ?: return false
val anchor = hitResult.createAnchor()
val node = ModelNode(modelFileLocation = "models/chair.glb")
node.anchor = anchor
arSceneView.addChild(node)
return true
}
}
Проверка isPoseInPolygon важна — hitTest может вернуть точку за краем обнаруженной плоскости, и объект повиснет в воздухе.
Augmented Images
AugmentedImageDatabase — для маркерного AR. База компилируется заранее через arcoreimg CLI (оценивает качество изображения, Score ≥ 75 для надёжного tracking):
arcoreimg eval-img --input_image_path=marker.png
# Image Quality Score: 87 (acceptable range: 0-100, >= 75 recommended)
val imageDatabase = AugmentedImageDatabase(session)
val bitmap = BitmapFactory.decodeStream(assets.open("marker.png"))
imageDatabase.addImage("product-marker", bitmap, 0.10f) // 10 см физически
config.augmentedImageDatabase = imageDatabase
Изображения с однородными цветами или симметричными паттернами дают низкий score — ARCore не может найти уникальные feature points. Логотипы с мелкими деталями работают лучше.
Тестирование на реальных устройствах
Эмулятор ARCore не даёт реального трекинга. Обязательно тестировать на:
- Флагмане (Pixel, Galaxy S-серия) — эталонная производительность
- Среднем классе (Samsung A-серия, Xiaomi Redmi Note) — реальная аудитория
- Устройстве без depth-сенсора — проверка деградации depth API
Firebase Test Lab поддерживает физические устройства с ARCore — можно автоматизировать базовые проверки запуска сессии.
Сроки
Базовая интеграция ARCore с plane detection и размещением GLB-модели: 3–5 дней. Augmented Images с базой маркеров и кастомным контентом: 5–8 дней. Полное решение с depth окклюзией, кастомным освещением и поддержкой 200+ устройств: 3–5 недель. Стоимость рассчитывается индивидуально после анализа требований.







