How to Create Google Lens Application in Android?

07 Mar, 2021
We have seen the new Google Lens application in which we can capture images of any product and from that image, we can get to see the search results of that product which we will display inside our application. 
We will be building a simple application in which we will be capturing an image from our device camera and after that, we will click on the Button to get the results for that product. A sample video is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Java language. 
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 that select Java as the programming language.
Step 2: Connect your app to Firebase
After creating a new project in Android Studio connect your app to Firebase. For connecting your app to firebase. Navigate to Tools on the top bar. After that click on Firebase. A new window will open on the right side. Inside that window click on Firebase ML and then click on Use Firebase ML kit in Android. You can see the option in the below screenshot.  
After clicking on this option you will get to see the below screen. On this screen click on Connect to Firebase option to connect your app to Firebase. You will get to see the below screen.  
Click on Connect option to connect your app to Firebase and add the below dependency to your build.gradle file.  
Step 3: Adding dependency for language translation to build.gradle file
Navigate to the app > Gradle Scripts > build.gradle file and add the below code to it. Comments are added in the code to get to know in more detail. 
// firebase dependencies.
implementation ‘com.google.firebase:firebase-core:15.0.2’
implementation ‘com.google.firebase:firebase-ml-vision:24.0.3’
implementation ‘com.google.firebase:firebase-ml-vision-image-label-model:20.0.1’
// below line is used for volley library
implementation ‘com.android.volley:volley:1.1.1’
// below line is used for image loading library
implementation ‘com.squareup.picasso:picasso:2.71828’
Step 4: Adding permissions to access the Internet and meta-data in your Android Apps AndroidManifest file
Navigate to the app > AndroidManifest.xml file and add the below code to it. Comments are added in the code to get to know in more detail. 
XML
<!-- below line is use to add camera feature in our app --><uses-feature  android:name="android.hardware.camera"  android:required="true" /><!-- permission for internet --><uses-permission android:name="android.permission.INTERNET" />
Add the below line inside your application tag.  
XML
<meta-data  android:name="com.google.firebase.ml.vision.DEPENDENCIES"  android:value="label" />
Below is the complete code for the AndroidManifest.xml file:
XML
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.googlelens">      <!-- below line is use to add camera feature in our app -->    <uses-feature        android:name="android.hardware.camera"        android:required="true" />    <!-- permission for internet -->    <uses-permission android:name="android.permission.INTERNET" />      <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.GoogleLens">        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                  <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>          <meta-data            android:name="com.google.firebase.ml.vision.DEPENDENCIES"            android:value="label" />      </application>  </manifest>
Step 5: Working with activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. 
XML
<?xml version="1.0" encoding="utf-8"?><RelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">          <!--image view for displaying our image-->    <ImageView        android:id="@+id/image"        android:layout_width="match_parent"        android:layout_height="300dp"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:layout_marginTop="10dp"        android:scaleType="centerCrop" />      <LinearLayout        android:id="@+id/idLLButtons"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@id/image"        android:orientation="horizontal">          <!--button for capturing our image-->        <Button            android:id="@+id/snapbtn"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:layout_margin="5dp"            android:layout_marginTop="30dp"            android:layout_weight="1"            android:lines="2"            android:text="Snap"            android:textAllCaps="false"            android:textSize="18sp"            android:textStyle="bold" />          <!--button for detecting the objects-->        <Button            android:id="@+id/idBtnSearchResuts"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:layout_margin="5dp"            android:layout_marginTop="30dp"            android:layout_weight="1"            android:lines="2"            android:text="Get Search Ressults"            android:textAllCaps="false"            android:textSize="18sp"            android:textStyle="bold" />      </LinearLayout>      <!--recycler view for displaying the list of result-->    <androidx.recyclerview.widget.RecyclerView        android:id="@+id/idRVSearchResults"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@id/idLLButtons" />      </RelativeLayout>
Step 6: Creating a modal class for storing our data
Navigate to the app > java > your app’s package name > Right-click on it > New > Java class and name your class as DataModal and add the below code to it. Comments are added inside the code to understand the code in more detail.
Java
public class DataModal {          // title for our search result.    private String title;          // link of our search result.    private String link;          // display link for our search result.    private String displayed_link;          // snippet for our search result.    private String snippet;      // constructor class.    public DataModal(String title, String link, String displayed_link, String snippet) {        this.title = title;        this.link = link;        this.displayed_link = displayed_link;        this.snippet = snippet;    }      // getter and setter methods.    public String getTitle() {        return title;    }      public void setTitle(String title) {        this.title = title;    }      public String getLink() {        return link;    }      public void setLink(String link) {        this.link = link;    }      public String getDisplayed_link() {        return displayed_link;    }      public void setDisplayed_link(String displayed_link) {        this.displayed_link = displayed_link;    }      public String getSnippet() {        return snippet;    }      public void setSnippet(String snippet) {        this.snippet = snippet;    }}
Step 7: Creating a layout file for displaying our RecyclerView items 
Navigate to the app > res > layout > Right-click on it > New > layout resource file and name it as search_result_rv_item and add the below code to it.   
XML
<?xml version="1.0" encoding="utf-8"?><androidx.cardview.widget.CardView    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="wrap_content"    android:layout_margin="5dp"    android:elevation="8dp"    app:cardCornerRadius="8dp">      <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">          <!--text view for our title-->        <TextView            android:id="@+id/idTVTitle"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:padding="4dp"            android:text="Title"            android:textColor="@android:color/holo_blue_dark"            android:textSize="15sp" />          <!--text view for our snippet-->        <TextView            android:id="@+id/idTVSnippet"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:padding="4dp"            android:text="Snippet"            android:textAllCaps="false"            android:textColor="@android:color/darker_gray"            android:textSize="12sp" />          <!--text view for our description-->        <TextView            android:id="@+id/idTVDescription"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:padding="3dp"            android:text="Description"            android:textColor="@android:color/darker_gray"            android:textSize="12sp" />      </LinearLayout>      </androidx.cardview.widget.CardView>
Step 8: Creating an adapter class for our RecyclerView
Navigate to the app > java > your app’s package name > Right-click on it > New > Java class and name it as SearchResultsRVAdapter and add the below code to it. 
Java
import android.content.Context;import android.content.Intent;import android.net.Uri;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;  import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView;  import java.util.ArrayList;  public class SearchResultsRVAdapter extends RecyclerView.Adapter<SearchResultsRVAdapter.ViewHolder> {          // arraylist for storing our data and context    private ArrayList<DataModal> dataModalArrayList;    private Context context;          // constructor for our variables.    public SearchResultsRVAdapter(ArrayList<DataModal> dataModalArrayList, Context context) {        this.dataModalArrayList = dataModalArrayList;        this.context = context;    }      @NonNull    @Override    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {        // inside on create view holder method we are inflating our layout file which we created.        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_result_rv_item, parent, false);        return new ViewHolder(view);    }      @Override    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {        // inside on bind view holder method we are setting        // data to each item of recycler view.        DataModal modal = dataModalArrayList.get(position);        holder.titleTV.setText(modal.getTitle());        holder.snippetTV.setText(modal.getDisplayed_link());        holder.descTV.setText(modal.getSnippet());        holder.itemView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // opening a link in your browser.                Intent i = new Intent(Intent.ACTION_VIEW);                i.setData(Uri.parse(modal.getLink()));                context.startActivity(i);            }        });    }      @Override    public int getItemCount() {        // returning the size of array list.        return dataModalArrayList.size();    }      public class ViewHolder extends RecyclerView.ViewHolder {        // creating variables for our text view.        private TextView titleTV, descTV, snippetTV;          public ViewHolder(@NonNull View itemView) {            super(itemView);            // initializing our views with their ids.            titleTV = itemView.findViewById(R.id.idTVTitle);            descTV = itemView.findViewById(R.id.idTVDescription);            snippetTV = itemView.findViewById(R.id.idTVSnippet);          }    }}
Step 9: Generating your API key
Go to the site https://serpapi.com/search-api and create your account with your Google account. This is a similar process as you signup on Geeks for Geeks. While generating your API key make sure to select the free trial option and proceed further. After going to the site shown above you will get to see the below screen. Simply sign in with your credentials and proceed further.
After proceeding further you have to simply Navigate to the My Account > Dashboard option to open the below screen. On this screen, you will get to see your API key.
Step 10: Working with the MainActivity.java file
Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.provider.MediaStore;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;  import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView;  import com.android.volley.Request;import com.android.volley.RequestQueue;import com.android.volley.Response;import com.android.volley.VolleyError;import com.android.volley.toolbox.JsonObjectRequest;import com.android.volley.toolbox.Volley;import com.google.android.gms.tasks.OnFailureListener;import com.google.android.gms.tasks.OnSuccessListener;import com.google.firebase.ml.vision.FirebaseVision;import com.google.firebase.ml.vision.common.FirebaseVisionImage;import com.google.firebase.ml.vision.label.FirebaseVisionImageLabel;import com.google.firebase.ml.vision.label.FirebaseVisionImageLabeler;  import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;  import java.util.ArrayList;import java.util.List;  public class MainActivity extends AppCompatActivity {      static final int REQUEST_IMAGE_CAPTURE = 1;          // variables for our image view, image bitmap,     // buttons, recycler view, adapter and array list.    private ImageView img;    private Button snap, searchResultsBtn;    private Bitmap imageBitmap;    private RecyclerView resultRV;    private SearchResultsRVAdapter searchResultsRVAdapter;    private ArrayList<DataModal> dataModalArrayList;    private String title, link, displayed_link, snippet;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                  // initializing all our variables for views        img = (ImageView) findViewById(R.id.image);        snap = (Button) findViewById(R.id.snapbtn);        searchResultsBtn = findViewById(R.id.idBtnSearchResuts);        resultRV = findViewById(R.id.idRVSearchResults);                  // initializing our array list        dataModalArrayList = new ArrayList<>();                  // initializing our adapter class.        searchResultsRVAdapter = new SearchResultsRVAdapter(dataModalArrayList, MainActivity.this);                  // layout manager for our recycler view.        LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);                  // on below line we are setting layout manager         // and adapter to our recycler view.        resultRV.setLayoutManager(manager);        resultRV.setAdapter(searchResultsRVAdapter);          // adding on click listener for our snap button.        snap.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // calling a method to capture an image.                dispatchTakePictureIntent();            }        });                  // adding on click listener for our button to search data.        searchResultsBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // calling a method to get search results.                getResults();            }        });    }      private void getResults() {        // inside the label image method we are calling a firebase vision image        // and passing our image bitmap to it.        FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(imageBitmap);                  // on below line we are creating a labeler for our image bitmap and         // creating a variable for our firebase vision image labeler.        FirebaseVisionImageLabeler labeler = FirebaseVision.getInstance().getOnDeviceImageLabeler();                  // calling a method to process an image and adding on success listener method to it.        labeler.processImage(image).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionImageLabel>>() {            @Override            public void onSuccess(List<FirebaseVisionImageLabel> firebaseVisionImageLabels) {                String searchQuery = firebaseVisionImageLabels.get(0).getText();                searchData(searchQuery);            }        }).addOnFailureListener(new OnFailureListener() {            @Override            public void onFailure(@NonNull Exception e) {                // displaying error message.                Toast.makeText(MainActivity.this, "Fail to detect image..", Toast.LENGTH_SHORT).show();            }        });    }      private void searchData(String searchQuery) {        String apiKey = "Enter your API key here";        String url = "https://serpapi.com/search.json?q=" + searchQuery.trim() + "&location=Delhi,India&hl=en&gl=us&google_domain=google.com&api_key=" + apiKey;                  // creating a new variable for our request queue        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {            @Override            public void onResponse(JSONObject response) {                try {                    // on below line we are extracting data from our json.                    JSONArray organicResultsArray = response.getJSONArray("organic_results");                    for (int i = 0; i < organicResultsArray.length(); i++) {                        JSONObject organicObj = organicResultsArray.getJSONObject(i);                        if (organicObj.has("title")) {                            title = organicObj.getString("title");                        }                        if (organicObj.has("link")) {                            link = organicObj.getString("link");                        }                        if (organicObj.has("displayed_link")) {                            displayed_link = organicObj.getString("displayed_link");                        }                        if (organicObj.has("snippet")) {                            snippet = organicObj.getString("snippet");                        }                        // on below line we are adding data to our array list.                        dataModalArrayList.add(new DataModal(title, link, displayed_link, snippet));                    }                    // notifying our adapter class                     // on data change in array list.                    searchResultsRVAdapter.notifyDataSetChanged();                } catch (JSONException e) {                    e.printStackTrace();                }            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError error) {                // displaying error message.                Toast.makeText(MainActivity.this, "No Result found for the search query..", Toast.LENGTH_SHORT).show();            }        });        // adding json object request to our queue.        queue.add(jsonObjectRequest);    }      // method to capture image.    private void dispatchTakePictureIntent() {        // inside this method we are calling an implicit intent to capture an image.        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {            // calling a start activity for result when image is captured.            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);        }    }      @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        // inside on activity result method we are         // setting our image to our image view from bitmap.        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {            Bundle extras = data.getExtras();            imageBitmap = (Bitmap) extras.get("data");            // on below line we are setting our            // bitmap to our image view.            img.setImageBitmap(imageBitmap);        }    }}
Now run your app and see the output of the app. Make sure to change your API key before running the app. 
Technical Scripter 2020
Android
Java
Technical Scripter
Java
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Add Views Dynamically and Store Data in Arraylist in Android?
Android SDK and it's Components
Flutter - Custom Bottom Navigation Bar
How to Communicate Between Fragments in Android?
Retrofit with Kotlin Coroutine in Android
Arrays.sort() in Java with examples
For-each loop in Java
Arrays in Java
Multidimensional Arrays in Java
Split() String method in Java with examples