Как создать простое приложение для Android с дополненной реальностью?

Опубликовано: 5 Января, 2022

Дополненная реальность прошла долгий путь от научно-фантастических историй до научной реальности. При такой скорости технического прогресса, вероятно, не так уж и далеко, когда мы также сможем манипулировать цифровыми данными в этом реальном физическом мире, как это сделал Тони Старк в своей лаборатории. Когда мы накладываем такую информацию, как звук, текст, изображение на наш реальный мир, а также можем взаимодействовать с ним через специальный носитель, то есть дополненную реальность. Всемирно известное приложение Pokemon GO - еще один пример приложения дополненной реальности. Давайте сделаем очень простое приложение дополненной реальности в Android Studio с использованием JAVA . Это приложение показывает изготовленную на заказ или загруженную 3D-модель с помощью камеры телефона. Ниже приведен образец GIF, чтобы понять, что мы собираемся делать в этой статье.

Терминологии

  • ARCore: Согласно Google, ARCore - это платформа для дополненной реальности. ARCore действительно помогает телефону ощущать окружающую среду и взаимодействовать с окружающим миром. ARCore в основном использует 3 ключевых принципа - отслеживание движения, понимание окружающей среды и оценка освещенности . Вот список телефонов, поддерживающих ARCore, предоставленный Google.
  • Sceneform: Согласно Google, Sceneform - это трехмерная структура, которая помогает разработчикам создавать приложения ARCore, не зная много об OpenGL. Sceneform имеет множество функций, таких как проверка разрешения камеры, управление 3D-активами и многое другое.

Пошаговая реализация

Шаг 1. Создайте новый проект

Чтобы создать новый проект в Android Studio, обратитесь к разделу «Как создать / запустить новый проект в Android Studio».

Note: 

  • Select Java as the programming language.
  • Note the location where the app is getting saved because we need that path later.
  • Choose ‘Minimum SDK‘ as ‘API 24: Android 7.0(Nougat)

Шаг 2: Получение 3D-модели

Scenform 1.16.0 поддерживает только файлы glTF. glTF означает формат передачи GL. Теперь файлы .glb представляют собой двоичную версию формата передачи GL. Эти типы файлов 3D-моделей используются в VR, AR, поскольку они поддерживают движение и анимацию.

  • Для 3D-модели необходимо получить файл .glb.
  • Есть два способа: вы можете взять 3D-модель, загрузить из Интернета или сделать ее самостоятельно .
  • Если вы хотите загрузить его из Интернета, перейдите в этот потрясающий репозиторий 3D-моделей от Google, poly и найдите любой файл glb . Загрузите любой из них для своего проекта.
  • ИЛИ, получите программное обеспечение для компьютерной 3D-графики и сделайте 3D-модель самостоятельно.
  • Я использовал Blender, который можно загрузить совершенно бесплатно, и сделал 3d модель текста GEEKS FOR GEEKS. Получите этот файл отсюда.
  • Экспортируйте модель в виде файла .glb в определенную папку, и имя файла должно содержать small_letters или числа .

  • Вернитесь в Android Studio.
  • На левой панели щелкните правой кнопкой мыши каталог res. Перейдите в Новый> Каталог ресурсов Android . Появится окно.

  • Измените тип ресурса : на Raw . Щелкните ОК . Необработанная папка создается в каталоге res.

  • Скопируйте файл . glb из того каталога, в котором вы его сохранили, и вставьте в исходную папку.

Шаг 3: загрузка и настройка SceneForm 1.16.0

Что ж, для приложений AR нам нужен Sceneform SDK. SceneForm 1.15.0 очень известен, но в последнее время я столкнулся с некоторыми ошибками плагина при установке плагина «Google Sceneform Tools (бета)» в последней версии Android Studio 4.1. Итак, я использую SDK Sceneform 1.16.0 и настраиваю его вручную.

  • Перейдите по этой ссылке GitHub.
  • Загрузите файл «sceneform-android-sdk-1.16.0.zip ».
  • Извлеките папки «sceneformsrc» и « sceneformux », в которых вы создали свой проект. («E: android ARApp» для меня)
  • Перейти в Android Studio
  • Перейдите в Gradle Scripts> settings.gradle (Настройки проекта)
  • Добавьте эти строки:

// this will add sceneformsrc folder into your project

include ‘:sceneform’

project(‘:sceneform’).projectDir = new File(‘sceneformsrc/sceneform’)

 

// this will add sceneformux folder into your project

include ‘:sceneformux’

project(‘:sceneformux’).projectDir = new File(‘sceneformux/ux’)

  • После этого перейдите в Gradle Scripts> build.gradle (Module: app)
  • Добавьте эту строку в блок зависимостей.

api project(“:sceneformux”)

  • Затем в том же файле внутри блока «android» и сразу после блока «buildTypes» добавьте следующие строки (если его еще нет):

// to support java 8 in your project

compileOptions {

       sourceCompatibility JavaVersion.VERSION_1_8

       targetCompatibility JavaVersion.VERSION_1_8

}

  • После всех этих изменений нажмите « Синхронизировать сейчас » во всплывающем окне выше. Теперь файловая структура Android будет выглядеть так.

  • Затем перейдите в приложение> манифесты> AndroidManifest.xml
  • Добавьте эти строки перед блоком «приложение »:

XML

<!--This permits the user to access Camera-->
< uses-permission android:name = "android.permission.CAMERA" />
<!--This helps to check a specific feature in the phone's hardware,
here it is OpenGlES version. Sceneform needs OpenGLES Version 3.0 or later-->
< uses-feature android:glEsVersion = "0x00030000" android:required = "true" />
<!--Indicates that this app requires Google Play Services for AR.
Limits app visibility in the Google Play Store to ARCore supported devices-->
< uses-feature android:name = "android.hardware.camera.ar" android:required = "true" />
  • После этого добавьте эту строку перед блоком «активность ».

XML

<!-- ARCore need to be installed, as the app does not include any non-AR features.
For an "AR Optional" app, specify "optional" instead of "required".-->
< meta-data android:name = "com.google.ar.core" android:value = "required" />

Ниже приведен полный код файла AndroidManifest.xml.

XML

<? xml version = "1.0" encoding = "utf-8" ?>
< manifest xmlns:android = " http://schemas.android.com/apk/res/android "
package = "com.wheic.arapp" >
<!--This helps to permit the user to access Camera-->
< uses-permission android:name = "android.permission.CAMERA" />
<!--This helps to check a specific feature in the phone's hardware,
here it is OpenGl ES version 3-->
< uses-feature
android:glEsVersion = "0x00030000"
android:required = "true" />
<!--Here it is checking for AR feature in phone camera-->
< uses-feature
android:name = "android.hardware.camera.ar"
android:required = "true" />
< application
android:allowBackup = "true"
android:icon = "@mipmap/ic_launcher"
android:label = "@string/app_name"
android:roundIcon = "@mipmap/ic_launcher_round"
android:supportsRtl = "true"
android:theme = "@style/Theme.ARApp" >
< meta-data
android:name = "com.google.ar.core"
android:value = "required" />
< activity android:name = ".MainActivity" >
< intent-filter >
< action android:name = "android.intent.action.MAIN" />
< category android:name = "android.intent.category.LAUNCHER" />
</ intent-filter >
</ activity >
</ application >
</ manifest >

Шаг 4: Исправление ошибок

А теперь немного скучно. Скачанные папки sceneformsrc и sceneformux содержат некоторый файл java, который импортирует классы java из более старой версии android.support. Итак, теперь, если вы создадите проект, вы увидите много ошибок из-за этого. Теперь вы можете перенести свой проект на новую версию Androidx . Теперь вы можете найти способ перенести весь проект на Androidx или изменить импорт вручную один за другим. Я знаю, что это скучно, но хорошие вещи приходят к тем, кто ждет, правда?

  • Перейдите в Build> Rebuild Project.
  • Вы найдете множество ошибок. Итак, в разделе «Сборка» дважды щелкните ошибку импорта пакета. Откроется код с выделенным разделом ошибок.
  • Вам нужно изменить только три типа пути импорта, указанные ниже, всякий раз, когда вы видите, что первый из них изменит его на второй:
    • android.support.annotation. -> androidx.annotation.
    • androidx.core.app -> androidx.fragment.app.
    • android.support.v7.widget. -> androidx.appcompat.widget.

  • Вы должны продолжать это до тех пор, пока ошибки не исчезнут.

Шаг 5: Работа с activity_main.xml файл

  • Перейдите в файл res> layout> activity_main.xml.
  • Вот код этого XML-файла:

XML

<? xml version = "1.0" encoding = "utf-8" ?>
< androidx.constraintlayout.widget.ConstraintLayout
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity" >
<!--This is the fragment that will be used as AR camera-->
< fragment
android:id = "@+id/arCameraArea"
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 >
  • ArFragment сам по себе содержит множество функций, например, он просит вас загрузить ARCore, если он еще не установлен в вашем телефоне, или запрашивает разрешение камеры, если оно еще не предоставлено. Так что лучше всего здесь использовать ArFragment.
  • После написания этого кода пользовательский интерфейс приложения будет выглядеть так:

Шаг 6: Работа с файлом MainActivity.java

  • Перейдите в java> com.wheic.arapp (ваш может отличаться) > MainActivity.java
  • В классе MainActivity сначала мы должны создать объект ArFragment.

Джава

// object of ArFragment Class
private ArFragment arCam;
  • Теперь давайте создадим функцию проверки оборудования вне функции onCreate () . Эта функция проверит, соответствует ли оборудование вашего телефона всем системным требованиям для запуска этого приложения AR. Он собирается проверить:
    • Версия API запущенного Android> = 24, что означает Android Nougat 7.0
    • Версия OpenGL> = 3.0
  • Их наличие обязательно для запуска приложений AR с использованием ARCore и Sceneform. Вот код этой функции:

Джава

public static boolean checkSystemSupport(Activity activity) {
// checking whether the API version of the running Android >= 24
// that means Android Nougat 7.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String openGlVersion = ((ActivityManager) Objects.requireNonNull(activity.getSystemService(Context.ACTIVITY_SERVICE))).getDeviceConfigurationInfo().getGlEsVersion();
// checking whether the OpenGL version >= 3.0
if (Double.parseDouble(openGlVersion) >= 3.0 ) {
return true ;
} else {
Toast.makeText(activity, "App needs OpenGl Version 3.0 or later" , Toast.LENGTH_SHORT).show();
activity.finish();
return false ;
}
} else {
Toast.makeText(activity, "App does not support required Build Version" , Toast.LENGTH_SHORT).show();
activity.finish();
return false ;
}
}
  • Сначала внутри функции onCreate () нам нужно проверить оборудование телефона. Если он вернет истину, то остальная часть функции будет выполнена.
  • Теперь ArFragment связан с соответствующим идентификатором, используемым в activity_main.xml .

Джава

// ArFragment is linked up with its respective id used in the activity_main.xml
arCam = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.arCameraArea);
  • Вызывается onTapListener , чтобы показать трехмерную модель, когда мы нажимаем на экран.
  • Внутри setOnTapArPlaneListener создается объект Anchor. Якорь действительно помогает вывести виртуальные объекты на экран и заставить их оставаться в том же положении и ориентации в пространстве.
  • Теперь класс ModelRenderable используется с множеством функций . Этот класс используется для рендеринга загруженной или созданной 3D-модели путем присоединения ее к AnchorNode.
    • Функция setSource () помогает получить исходный код 3d модели.
    • Функция setIsFilamentGltf () проверяет, является ли это файлом glb.
    • Функция build () отображает модель.
    • Функция вызывается внутри функции thenAccept () для получения модели путем присоединения AnchorNode к ModelRenderable.
    • Функция exceptionally () генерирует исключение, если что-то пойдет не так при построении модели.

Джава

arCam.setOnTapArPlaneListener((hitResult, plane, motionEvent) -> {
clickNo++;
// the 3d model comes to the scene only the first time we tap the screen
if (clickNo == 1 ) {
Anchor anchor = hitResult.createAnchor();
ModelRenderable.builder()
.setSource( this , R.raw.gfg_gold_text_stand_2)
.setIsFilamentGltf( true )
.build()
.thenAccept(modelRenderable -> addModel(anchor, modelRenderable))
.exceptionally(throwable -> {
AlertDialog.Builder builder = new AlertDialog.Builder( this );
builder.setMessage( "Somthing is not right" + throwable.getMessage()).show();
return null ;
});
}
});
  • Теперь посмотрим, что находится в функции addModel ():
    • Он принимает два параметра: первый - это Anchor, а второй - ModelRenderable.
    • Создается объект AnchorNode. Это корневой узел сцены. AnchorNode автоматически позиционируется в мире на основе привязки.
    • TransformableNode помогает пользователю взаимодействовать с 3D-моделью, например изменять положение, изменять размер, вращать и т. Д.

Джава

private void addModel(Anchor anchor, ModelRenderable modelRenderable) {
// Creating a AnchorNode with a specific anchor
AnchorNode anchorNode = new AnchorNode(anchor);
// attaching the anchorNode with the ArFragment
anchorNode.setParent(arCam.getArSceneView().getScene());
TransformableNode transform = new TransformableNode(arCam.getTransformationSystem());
// attaching the anchorNode with the TransformableNode
transform.setParent(anchorNode);
// attaching the 3d model with the TransformableNode that is
// already attached with the node
transform.setRenderable(modelRenderable);
transform.select();
}

Вот полный код файла MainActivity.java. Комментарии добавляются внутри кода для более подробного понимания кода.

Джава

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.ar.core.Anchor;
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;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
// object of ArFragment Class
private ArFragment arCam;
// helps to render the 3d model
// only once when we tap the screen
private int clickNo = 0 ;
public static boolean checkSystemSupport(Activity activity) {
// checking whether the API version of the running Android >= 24
// that means Android Nougat 7.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String openGlVersion = ((ActivityManager) Objects.requireNonNull(activity.getSystemService(Context.ACTIVITY_SERVICE))).getDeviceConfigurationInfo().getGlEsVersion();
// checking whether the OpenGL version >= 3.0
if (Double.parseDouble(openGlVersion) >= 3.0 ) {
return true ;
} else {
Toast.makeText(activity, "App needs OpenGl Version 3.0 or later" , Toast.LENGTH_SHORT).show();
activity.finish();
return false ;
}
} else {
Toast.makeText(activity, "App does not support required Build Version" , Toast.LENGTH_SHORT).show();
activity.finish();
return false ;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkSystemSupport( this )) {
// ArFragment is linked up with its respective id used in the activity_main.xml
arCam = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.arCameraArea);
arCam.setOnTapArPlaneListener((hitResult, plane, motionEvent) -> {
clickNo++;
// the 3d model comes to the scene only
// when clickNo is one that means once
if (clickNo == 1 ) {
Anchor anchor = hitResult.createAnchor();
ModelRenderable.builder()
.setSource( this , R.raw.gfg_gold_text_stand_2)
.setIsFilamentGltf( true )
.build()
.thenAccept(modelRenderable -> addModel(anchor, modelRenderable))
.exceptionally(throwable -> {
AlertDialog.Builder builder = new AlertDialog.Builder( this );
builder.setMessage( "Somthing is not right" + throwable.getMessage()).show();
return null ;
});
}
});
} else {
return ;
}
}
private void addModel(Anchor anchor, ModelRenderable modelRenderable) {
// Creating a AnchorNode with a specific anchor
AnchorNode anchorNode = new AnchorNode(anchor);
// attaching the anchorNode with the ArFragment
anchorNode.setParent(arCam.getArSceneView().getScene());
// attaching the anchorNode with the TransformableNode
TransformableNode model = new TransformableNode(arCam.getTransformationSystem());
model.setParent(anchorNode);
// attaching the 3d model with the TransformableNode
// that is already attached with the node
model.setRenderable(modelRenderable);
model.select();
}
}

Вывод: запуск на физическом устройстве

Наконец, мы создали простое приложение дополненной реальности с помощью Android Studio. Вы можете проверить этот проект по этой ссылке на GitHub.

Хотите более динамичную и конкурентную среду для изучения основ Android?
Щелкните здесь, чтобы перейти к уникальному руководству, составленному нашими экспертами с целью мгновенно подготовить вашу отрасль!