环境准备
1. 工具与设备要求
-
Android Studio:Arctic Fox 或更高版本
-
设备 :支持 ARCore 的 Android 设备(查看支持列表)
-
依赖库 :
gradle// build.gradle (Module级) dependencies { implementation 'com.google.ar:core:1.35.0' implementation 'com.google.ar.sceneform:core:1.17.1' implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.17.1' }
基础实现步骤
1. 配置 AndroidManifest.xml
xml
<!-- 添加权限和AR特性 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.ar" android:required="true" />
<application>
<!-- 声明AR元数据 -->
<meta-data
android:name="com.google.ar.core"
android:value="required" />
</application>
2. 创建完整布局文件
xml
<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/arFragment"
android:name="com.google.ar.sceneform.ux.ArFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
3. 完整 Kotlin 主活动代码
kotlin
// MainActivity.kt
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.ar.core.ArCoreApk
import com.google.ar.core.Config
import com.google.ar.core.Session
import com.google.ar.sceneform.AnchorNode
import com.google.ar.sceneform.rendering.ModelRenderable
import com.google.ar.sceneform.ux.ArFragment
import com.google.ar.sceneform.ux.TransformableNode
class MainActivity : AppCompatActivity() {
private lateinit var arFragment: ArFragment
private var isArSupported = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
checkARSupport()
setupARScene()
}
// 检查AR支持性
private fun checkARSupport() {
val availability = ArCoreApk.getInstance().checkAvailability(this)
when {
availability.isSupported -> {
isArSupported = true
ArCoreApk.getInstance().requestInstall(this, true)
}
availability.isTransient -> {
// 如果状态是暂时未知,延迟后重新检查
Handler(Looper.getMainLooper()).postDelayed({
checkARSupport()
}, 200)
}
else -> {
Toast.makeText(this, "设备不支持AR", Toast.LENGTH_LONG).show()
finish()
}
}
}
// 初始化AR场景
private fun setupARScene() {
arFragment = supportFragmentManager.findFragmentById(R.id.arFragment) as ArFragment
// 配置AR会话
arFragment.arSceneView.scene.addOnUpdateListener { frameTime ->
arFragment.arSceneView.scene
.getCamera()
?.let { camera ->
// 在此处添加每帧更新的逻辑
}
}
// 设置点击监听器
arFragment.setOnTapArPlaneListener { hitResult, plane, motionEvent ->
placeModel(hitResult.createAnchor())
}
}
// 放置3D模型
private fun placeModel(anchor: Anchor) {
ModelRenderable.builder()
.setSource(this, Uri.parse("model.sfb")) // 替换为你的模型路径
.build()
.thenAccept { modelRenderable ->
val anchorNode = AnchorNode(anchor)
anchorNode.setParent(arFragment.arSceneView.scene)
val modelNode = TransformableNode(arFragment.transformationSystem)
modelNode.renderable = modelRenderable
modelNode.setParent(anchorNode)
modelNode.select() // 自动显示变换控制器
}
.exceptionally { throwable ->
Toast.makeText(this, "模型加载失败: ${throwable.message}", Toast.LENGTH_LONG).show()
null
}
}
}
4. 模型资源配置
-
准备模型文件 :
-
将
.obj
和.mtl
文件放入app/src/main/assets
-
创建
model.sfa
描述文件:json// model.sfa { "resources": [ { "filename": "model.obj", "material": "model.mtl" } ] }
-
-
配置 Gradle 转换任务 :
gradleplugins { id 'com.google.ar.sceneform.plugin' } sceneform.asset( 'src/main/assets/model.obj', 'default', 'src/main/assets/model.sfa', 'src/main/assets/model.sfb' )
高级功能扩展
1. 平面检测可视化
kotlin
// 在setupARScene()中添加:
arFragment.arSceneView.planeRenderer.isVisible = true
arFragment.arSceneView.planeRenderer.material
.thenAccept { material ->
material.setFloat3("color", Color(0.3f, 0.7f, 0.3f))
}
2. 光照估计
kotlin
// 在每帧更新中获取光照信息
arFragment.arSceneView.scene.addOnUpdateListener { frameTime ->
val frame = arFragment.arSceneView.arFrame
val lightEstimate = frame?.lightEstimate
lightEstimate?.let {
val intensity = it.pixelIntensity
// 根据光照强度调整模型材质
}
}
常见问题解决
1. 黑屏问题排查
-
检查相机权限是否动态申请:
kotlin// 在onCreate()中添加权限检查 if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION) }
2. 模型位置偏移
-
调整模型原点:
kotlinmodelNode.localPosition = Vector3(0f, 0.5f, 0f) // 在Y轴上抬高0.5米
完整项目结构
app/
├── src/
│ ├── main/
│ │ ├── assets/
│ │ │ ├── model.obj
│ │ │ ├── model.mtl
│ │ │ └── model.sfa
│ │ ├── java/
│ │ │ └── com.example.arapp/
│ │ │ └── MainActivity.kt
│ │ └── res/
│ │ └── layout/
│ │ └── activity_main.xml
└── build.gradle
运行与调试
-
设备要求 :
- 确保设备已安装 Google Play Services for AR
-
调试技巧 :
kotlin// 启用调试模式 arFragment.arSceneView.arFrame?.let { frame -> Log.d("AR_DEBUG", "跟踪状态: ${frame.camera.trackingState}") }
下一步学习方向
- 手势交互:实现模型的旋转/缩放/平移
- 遮挡处理:使用深度API实现真实遮挡效果
- 多人共享:通过Cloud Anchors实现多设备协同
建议从简单模型开始,逐步添加复杂功能。