How to Build a Simple Augmented Reality Android App? (original) (raw)

Last Updated : 27 Sep, 2025

Augmented Reality has crossed a long way from Sci-fi Stories to Scientific reality. With this speed of technical advancement, it's probably not very far when we can also manipulate digital data in this real physical world as Tony Stark did in his lab. When we superimpose information like sound, text, image to our real-world and also can interact with it through a special medium, that is Augmented Reality. The world-famous "Pokemon GO" app is just another example of an Augmented Reality Application. Let's make a very simple Augmented Reality App in **Android Studio using JAVA. This app shows a custom made or downloaded 3d model using the phone camera. A sample GIF is given below to get an idea about what we are going to do in this article.

**Terminologies

**Step by Step Implementation

**Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.

**Note:

2-660x455-min

**Step 2: Getting the 3D Model

Sceneform 1.16.0 supports only **glTF files. glTF means GL Transmission Format. Now ****.glb** files are a binary version of the GL Transmission Format. These types of 3d model files are used in VR, AR because it supports motion and animation.

6-660x184-min

9-(1)

10-min

**Step 3: Downloading and Setting up SceneForm 1.16.0

Well, for AR apps we need Sceneform SDK. SceneForm 1.15.0 is very famous but recently, there are some plugin errors I faced while getting the "Google Sceneform Tools (Beta)" plugin in the latest Android Studio 4.1. So here I am, using the Sceneform 1.16.0 SDK and setting it up manually.

// 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')

api project(":sceneformux")

dependencies {

implementation 'com.google.ar:core:1.32.0'
}

// to support java 8 in your project

compileOptions {

sourceCompatibility JavaVersion.VERSION_1_8

targetCompatibility JavaVersion.VERSION_1_8

}

Build a Simple Augmented Reality Android App

`

After that add this line before the "**activity" block.

XML `

`

Below is the complete code for the **AndroidManifest.xml file.

XML `

<!--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>

`

**Step 4: Error Correction

Now comes a little boring part. The downloaded folders **sceneformsrc and **sceneformux contains some java file, that imports the java classes from an older android.support. So, now if you build the project you will see a lot of errors because of that. What you can do now is to migrate your project to the new **Androidx. Now, you can find a way to migrate your whole project to **Androidx or you can change the imports manually one by one. I know this is boring, but good things come to those who wait, right?

31-(2)

4-(1)

**Step 5: Working with the activity_main.xml **file

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" 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>

`

7-660x645-(1)

**Step 6: Working with MainActivity.java file

// object of ArFragment Class private ArFragment arCam;

`

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;
}

}

`

// 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 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("Something is not right" + throwable.getMessage()).show();
                return null;
            });
}

});

`

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();

}

`

Here is the complete code of the **MainActivity.java file. Comments are added inside the code to understand the code in more detail.

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("Something 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();
}

}

`

**Output: Run on a Physical Device

Finally, we built a simple Augmented Reality app using Android Studio. You can check this project in this **GitHub link.