在本教程中,我们将学习如何用Kotlin创建一个增强现实的应用程序,以跟上快速发展的科技世界。这个应用程序将允许你使用手机的摄像头为图片添加属性。
前提条件
读者应该具备以下条件才能跟上。
- 在你的机器上安装最新版本的Android Studio。
- 你应该有Kotlin编程语言的知识。
- 拥有一个由Google Play服务支持的AR的物理设备。
注意:不是所有的安卓设备都支持ARcore。从这里查看支持的设备列表。另外,值得注意的是,你可以在安卓模拟器上运行该应用程序。要了解如何做到这一点,请点击本指南。
目标
在本教程结束时,读者将了解到以下内容。
- 什么是增强现实(Augmented Reality)。
- 如何为增强现实设置一个安卓工作室。
- 如何在AR场景中放置3D物体。
什么是增强现实(AR)?
这是一个现实世界的技术增强版本。它是通过使用合成图形元素、音乐或其他感官刺激来创建的。
它是一项新技术,将数字元素与现实世界的物体融合在一起。手机用户可以使用他们的智能手机与他们的环境互动。有了AR,我们可以按照自己的意愿弯曲现实,这就像现实的延伸,或者可以说,重新评估未来。
创建一个安卓项目
启动Android Studio并创建一个新项目。

注意:最小的SDK版本应该是API 24:Android 7(Nougat)。
项目准备好后,我们需要添加Sceneform 插件。这个插件对于支持增强现实技术是必要的。
在Android Studio的菜单上,点击File ,然后点击Settings ,一个新的窗口将打开。在右边的标签上,点击Plugins ,并在市场上搜索Sceneform 。点击安装并应用。重新启动Android Studio以使变化生效。
安装Sceneform插件

在IDE重启后,你可能会注意到弹出的一个错误。这个错误的内容如下。
"插件错误。插件'Google Sceneform Tools(Beta)'只与IntelliJ IDEA兼容,因为它没有定义任何明确的模块依赖关系"。
你可以通过使用Sceneform SDK v1.16.0来解决这个错误。另外,你可以手动设置一切。
手动设置
-
从这里下载Sceneform文件。将这些文件解压到你的应用程序的文件夹中,然后进入下一个步骤。
-
进入Gradle,打开
gradle.settings,添加以下几行。
include ':sceneform'
project(':sceneform').projectDir = new File('sceneformsrc/sceneform')
include ':sceneformux'
project(':sceneformux').projectDir = new File('sceneformux/ux')
- 打开
build.gradle(Module:app),在依赖项中添加以下一行。
api project(":sceneformux")
- 用新的Gradle文件同步项目,并等待构建完成。
在Android Studio中设置AR 3D模型
在我们的项目中,我们将使用Sceneform SDK 1.15.0,它非常流行。有两种方法可以获得3D模型。
-
你可以在网上获得3D模型,并下载
glb文件。最初使用的是谷歌的Poly,但后来被废止了。你可以在网上找到其他的替代品,其中一些你可能要为模型付费。Sketchfab是一个很好的例子,但你必须购买它。 -
自己设计和建造模型。你可以使用Blender这样的软件来制作3D模型,你可以在你的应用程序中使用。
在本教程中,我们将使用一个现成的模型,可以从这里下载。
下载完模型后,进入Android Studio,在res 文件夹上,右键单击并创建一个新的Android Resource Directory 。将资源类型改为raw ,然后点击确定。在这个目录中,粘贴你刚刚下载的model.glb 文件。
启用权限
打开Manifest ,添加以下权限。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:glEsVersion="0x00030000" android:required="true"/>
<uses-feature android:name="android.hardware.camera.ar" android:required="true"/>
另外,在<application> 体中,添加以下元数据。
<application ..>
...
<meta-data
android:name="com.google.ar.core"
android:value="required" />
...
</application
建立应用程序的用户界面
该应用程序将只需要一个屏幕,这将是相机屏幕。打开activity_main.xml ,并添加以下代码。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/sceneform_ar_scene_view"
android:name="com.google.ar.sceneform.ux.ArFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
在android:name="com.google.ar.sceneform.ux.ArFragment" 行可能会出现一个错误。这是因为没有找到ArFragment 类。
为了解决这个问题,打开build.gradle 应用程序级别,添加以下依赖关系并同步项目。
implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.17.1'
实现应用程序的主要逻辑
打开ActivityMain.kt 文件,首先创建一个函数,检查一个设备是否支持ARcore。这个函数应该是这样的。
private const val MIN_OPENGL_VERSION = 3.0
private fun isDeviceArSupported(context : Context) : Boolean {
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
val openGlVersionString = (context.getSystemService(AppCompatActivity.ACTIVITY_SERVICE) as ActivityManager)
.deviceConfigurationInfo
.glEsVersion
if (openGlVersionString.toDouble() < MIN_OPENGL_VERSION) {
Toast.makeText(this, "Minimum Open GL version should be 3 or later", Toast.LENGTH_LONG)
.show()
this.finish()
return false
}
return true
}
else -> {
Toast.makeText(this, "Android version should be 7 or later versions",
Toast.LENGTH_LONG
)
.show()
this.finish()
return false
}
}
}
使用手机的Open GL版本,上述函数检查一个设备是否支持AR。对于一个完全支持AR的设备来说,它必须是安卓7或更高版本,最小的Open GL版本应该是3。
下一步是将我们的模型添加到一个场景中。这将通过创建一个将节点放入AR场景的函数来完成。该函数如下。
private fun addModelToScene(arFragment: ArFragment, anchor: Anchor, renderable: Renderable) {
val transformableNode = TransformableNode(arFragment.transformationSystem)
transformableNode.renderable = renderable
val anchorNode = AnchorNode(anchor)
transformableNode.setParent(anchorNode)
arFragment.arSceneView.scene.addChild(anchorNode)
transformableNode.select()
}
最后一件事是在AR场景中放置物体。这可以通过以下方式完成。
@RequiresApi(Build.VERSION_CODES.N)
private fun placeObjectOnScene(fragment: ArFragment, anchor: Anchor, uri: Uri) {
ModelRenderable.builder()
.setSource(fragment.context, uri)
.build()
.thenAccept(Consumer { renderable: ModelRenderable? ->
addModelToScene(
fragment, anchor, renderable!!
)
})
.exceptionally { throwable: Throwable ->
Toast.makeText(
fragment.context, "Error:" + throwable.message,
Toast.LENGTH_LONG
).show()
null
}
}
注意:记得用
@RequiresApi(Build.VERSION_CODES.N)注释,以确保该函数只在Android 7或更高版本上调用。
完整的MainActivity.kt 代码如下。
private const val MIN_OPENGL_VERSION = 3.0
class MainActivity : AppCompatActivity() {
private lateinit var arFragment: ArFragment
private lateinit var binding: ActivityMainBinding
@RequiresApi(VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (isDeviceArSupported(this)) {
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
arFragment =
(supportFragmentManager.findFragmentById(R.id.sceneform_ar_scene_view) as ArFragment?)!!
this.arFragment!!.setOnTapArPlaneListener { hitResult: HitResult, plane: Plane?, motionEvent: MotionEvent? ->
val anchor = hitResult.createAnchor()
placeObjectOnScene(arFragment!!, anchor, Uri.parse("model.glb"))
}
}
}
private fun isDeviceArSupported(context: Context): Boolean {
when {
Build.VERSION.SDK_INT >= VERSION_CODES.N -> {
val openGlVersionString =
(context.getSystemService(ACTIVITY_SERVICE) as ActivityManager)
.deviceConfigurationInfo
.glEsVersion
if (openGlVersionString.toDouble() < MIN_OPENGL_VERSION) {
Toast.makeText(
this, "Minimum Open GL version should be 3 or later",
Toast.LENGTH_LONG
).show()
this.finish()
return false
}
return true
}
else -> {
Toast.makeText(
this, "Android version should be 7 or later versions",
Toast.LENGTH_LONG
)
.show()
this.finish()
return false
}
}
}
private fun addModelToScene(arFragment: ArFragment, anchor: Anchor, renderable: Renderable) {
val transformableNode = TransformableNode(arFragment.transformationSystem)
transformableNode.renderable = renderable
val anchorNode = AnchorNode(anchor)
transformableNode.setParent(anchorNode)
arFragment.arSceneView.scene.addChild(anchorNode)
transformableNode.select()
}
@RequiresApi(VERSION_CODES.N)
private fun placeObjectOnScene(fragment: ArFragment, anchor: Anchor, uri: Uri) {
ModelRenderable.builder()
.setSource(fragment.context, uri)
.build()
.thenAccept(Consumer { renderable: ModelRenderable? ->
addModelToScene(
fragment, anchor, renderable!!
)
})
.exceptionally { throwable: Throwable ->
Toast.makeText(
fragment.context, "Error:" + throwable.message,
Toast.LENGTH_LONG
)
.show()
null
}
}
}
运行该应用程序
要运行该应用程序,首先要确保你的设备上有一个活跃的互联网连接。运行该应用程序,并将焦点放在一个表面上。谷歌AR将开始检测一个表面,在它检测到之后,点击屏幕,将我们的物体放在那里。然后,你可以在不同的表面上尝试这样做,因为你在探索。
总结
在本教程中,我们已经学会了如何创建一个增强现实的应用程序,并在场景中放置物体。AR的作用不止于此。通过阅读更多关于这个主题的文章,继续探索更多关于增强现实的内容。
编码愉快 :)