Android – AutoCompleteTextView with Google Places Autocomplete API

March 5, 2013
By

In this article, we will develop and Android application which populates an AutoCompleteTextView with Google Places Autocomplete api.

This application is developed in Eclipse (4.2.1) with ADT plugin (21.1.0) and Android SDK ( 21.1.0 ).


1. Create a new Android application project namely “LocationPlacesAutocomplete”

Create new Android application project

Figure 1 : Create new Android application project


2. Configure the project

Configure application project

Figure 2 : Configure application project


3. Design application launcher icon

Design application launcher icon

Figure 3 : Design application launcher icon


4. Create a blank activity

Create a blank activity

Figure 4 : Create a blank activity


5. Enter MainActivity details

Enter MainActivity details

Figure 5 : Enter MainActivity details


6. Get the API key for Google Places API

We can create API key for Google Place API by clicking “Create new Browser key”  available at the “API Access” pane of the Google console URL : http://code.google.com/apis/console.

Also ensure that, “Places API” is enabled in the “Services” pane of the Google console.


7. Update the file res/values/strings.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">LocationPlacesAutocomplete</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="str_atv_places">Enter Place Here</string>
</resources>


8. Create a new class namely “CustomAutoCompleteTextView” in the file src/in/wptrafficanalyzer/locationplacesautocomplete/CustomAutoCompleteTextView.java


package in.wptrafficanalyzer.locationplacesautocomplete;

import java.util.HashMap;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.AutoCompleteTextView;

/** Customizing AutoCompleteTextView to return Place Description
 * corresponding to the selected item
 */
public class CustomAutoCompleteTextView extends AutoCompleteTextView {

    public CustomAutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /** Returns the place description corresponding to the selected item */
    @Override
    protected CharSequence convertSelectionToString(Object selectedItem) {
        /** Each item in the autocompetetextview suggestion list is a hashmap object */
        HashMap<String, String> hm = (HashMap<String, String>) selectedItem;
        return hm.get("description");
    }
}

9. Update the layout file res/layout/activity_main.xml


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

    <in.wptrafficanalyzer.locationplacesautocomplete.CustomAutoCompleteTextView
        android:id="@+id/atv_places"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:hint="@string/str_atv_places" />
</RelativeLayout>

10. Create a new class namely “PlaceJSONParser” in the file src/in/wptrafficanalyzer/locationplacesautocomplete/PlaceJSONParser.java


package in.wptrafficanalyzer.locationplacesautocomplete;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class PlaceJSONParser {

/** Receives a JSONObject and returns a list */
    public List<HashMap<String,String>> parse(JSONObject jObject){

        JSONArray jPlaces = null;
        try {
            /** Retrieves all the elements in the 'places' array */
            jPlaces = jObject.getJSONArray("predictions");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        /** Invoking getPlaces with the array of json object
         * where each json object represent a place
        */
        return getPlaces(jPlaces);
    }

    private List<HashMap<String, String>> getPlaces(JSONArray jPlaces){
        int placesCount = jPlaces.length();
        List<HashMap<String, String>> placesList = new ArrayList<HashMap<String,String>>();
        HashMap<String, String> place = null;

        /** Taking each place, parses and adds to list object */
        for(int i=0; i<placesCount;i++){
            try {
                /** Call getPlace with place JSON object to parse the place */
                place = getPlace((JSONObject)jPlaces.get(i));
                placesList.add(place);

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        return placesList;
    }

    /** Parsing the Place JSON object */
    private HashMap<String, String> getPlace(JSONObject jPlace){

        HashMap<String, String> place = new HashMap<String, String>();

        String id="";
        String reference="";
        String description="";

        try {

            description = jPlace.getString("description");
            id = jPlace.getString("id");
            reference = jPlace.getString("reference");

            place.put("description", description);
            place.put("_id",id);
            place.put("reference",reference);

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return place;
    }
}


11. Update the class “MainActivity” in the file src/in/wptrafficanalyzer/locationplacesautocomplete/MainActivity.java


package in.wptrafficanalyzer.locationplacesautocomplete;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;

import org.json.JSONObject;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.widget.AutoCompleteTextView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

    AutoCompleteTextView atvPlaces;
    PlacesTask placesTask;
    ParserTask parserTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        atvPlaces = (AutoCompleteTextView) findViewById(R.id.atv_places);
        atvPlaces.setThreshold(1);

        atvPlaces.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                placesTask = new PlacesTask();
                placesTask.execute(s.toString());
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
                // TODO Auto-generated method stub
            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
            }
        });
    }

    /** A method to download json data from url */
    private String downloadUrl(String strUrl) throws IOException{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
            URL url = new URL(strUrl);

            // Creating an http connection to communicate with url
            urlConnection = (HttpURLConnection) url.openConnection();

            // Connecting to url
            urlConnection.connect();

            // Reading data from url
            iStream = urlConnection.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

            StringBuffer sb = new StringBuffer();

            String line = "";
            while( ( line = br.readLine()) != null){
                sb.append(line);
            }

            data = sb.toString();

            br.close();

        }catch(Exception e){
            Log.d("Exception while downloading url", e.toString());
        }finally{
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }

    // Fetches all places from GooglePlaces AutoComplete Web Service
    private class PlacesTask extends AsyncTask<String, Void, String>{

        @Override
        protected String doInBackground(String... place) {
            // For storing data from web service
            String data = "";

            // Obtain browser key from https://code.google.com/apis/console
            String key = "key=YOUR_API_KEY";

            String input="";

            try {
                input = "input=" + URLEncoder.encode(place[0], "utf-8");
            } catch (UnsupportedEncodingException e1) {
                e1.printStackTrace();
            }

            // place type to be searched
            String types = "types=geocode";

            // Sensor enabled
            String sensor = "sensor=false";

            // Building the parameters to the web service
            String parameters = input+"&"+types+"&"+sensor+"&"+key;

            // Output format
            String output = "json";

            // Building the url to the web service
            String url = "https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+parameters;

            try{
                // Fetching the data from we service
                data = downloadUrl(url);
            }catch(Exception e){
                Log.d("Background Task",e.toString());
            }
            return data;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            // Creating ParserTask
            parserTask = new ParserTask();

            // Starting Parsing the JSON string returned by Web Service
            parserTask.execute(result);
        }
    }
    /** A class to parse the Google Places in JSON format */
    private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String,String>>>{

        JSONObject jObject;

        @Override
        protected List<HashMap<String, String>> doInBackground(String... jsonData) {

            List<HashMap<String, String>> places = null;

            PlaceJSONParser placeJsonParser = new PlaceJSONParser();

            try{
                jObject = new JSONObject(jsonData[0]);

                // Getting the parsed data as a List construct
                places = placeJsonParser.parse(jObject);

            }catch(Exception e){
                Log.d("Exception",e.toString());
            }
            return places;
        }

        @Override
        protected void onPostExecute(List<HashMap<String, String>> result) {

            String[] from = new String[] { "description"};
            int[] to = new int[] { android.R.id.text1 };

            // Creating a SimpleAdapter for the AutoCompleteTextView
            SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1, from, to);

            // Setting the adapter
            atvPlaces.setAdapter(adapter);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

Note : Replace “YOUR_API_KEY” at 108 with the api key obtained in the Step 6


12. Update the file AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.wptrafficanalyzer.locationplacesautocomplete"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="in.wptrafficanalyzer.locationplacesautocomplete.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>



13. Screenshots of the application

User inputs name of place in AutoCompleteTextView

Figure 6 : User inputs name of place in AutoCompleteTextView

User selects a place from the AutoCompleteTextView dropdown list

Figure 7 : User selected a place from the AutoCompleteTextView dropdown list


14. Download Source Code


How to hire me?

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in

You can hire me on hourly basis or on project basis for Android applications development.

For hiring me, please mail your requirements to info@wptrafficanalyzer.in.

My other blogs
store4js.blogspot.com


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: , , ,

52 Responses to Android – AutoCompleteTextView with Google Places Autocomplete API

  1. Mario on May 4, 2013 at 3:28 pm

    Thanks for this tutorial! I have a little problem. I installed this app on emulator (for now i don’t have real device) and it works until i want specify more details; in the sense that when i type “Rome” suggestions come..when i type “Rome via” there is an exception “null pointer exception during performfiltering()” and no suggestions is shown. Every time i add more than one parameter (and also white space) this happens. I don’t know if it is a problem of emulator or not because i can try on real device…many thanks!

    • george on May 6, 2013 at 8:45 am

      Hello Mario,

      Thank you for such a nice comment here. Suggestions on the reported issues are listed below :

      Issue 1 : “null pointer exception during performfiltering()”

      The null pointer exception is due to broken url on entering the space in the autocomplete textview.

      This is a bug in our code and can be fixed by encoding the variable “input”. See the corrected code at the line 113 of the class MainActivity.

      Issue 2 : “no suggestions is shown when more than one parameter is added”

      This is the default behavior of the adapter used in autocompletetextview.

      • Mario on May 6, 2013 at 6:26 pm

        thanks a lot for your suggestions!

        • Joe on July 22, 2013 at 4:42 am

          And how can this default behavior be changed?

      • Pratik Borole on January 7, 2014 at 4:16 pm

        Please tell me how to incorporate more than one parameter in the adapter used in autocompletetextview. I cant, for the life of me, find any reference to the same. I have an app under development & I really need it. I’d appreciate it if you help me out.

        Thanx in advance.

      • Siddhi on July 7, 2016 at 10:31 pm

        Can you suggest a way to be able to work this out for more than one parameter too?
        Thanks in advance

  2. Karthik on May 27, 2013 at 2:22 am

    Hi,
    The tutorial is very good, but then when I import the project and run it on my android tablet, its raising a null pointer exception immediately I start typing in the text field.

    Would be grateful if you could please help me in this aspect!
    thanks in advance!

  3. bramara on July 25, 2013 at 3:27 pm

    Hi, your Example is nice but its not working for me .. i didn’t find any autocomplete textview…
    is there any special procedure and reqirements for generating browser key?
    please help me

    thanks for your time..

  4. Narasimha on August 5, 2013 at 3:49 pm

    Hi, your Example is nice but its not working for me .. i didn’t find any autocomplete textview…
    is there any special procedure and reqirements for generating browser key?
    please help me

    thanks for your time..

  5. farrakh javed on August 13, 2013 at 2:34 pm

    Hi. I have implemented above functionality. Now i want to implement search functionality for other languages like in textbox if i enter value in arabic then how to get result in arabic. Main issue is how to make search in arabic.
    Thanks in advance.

    • Rupal bhanderi on March 17, 2016 at 12:49 pm

      hello this functionality is working for u?/
      then plz send me your demo code plz bcz i can’t so plz.

  6. Bibin on August 30, 2013 at 1:45 pm

    i am a newbie to android. i am doing my project work in android. Location based reminder. i need this auto-completion box in this reminder utility. This one is not working for me. enabled places API in console and generated a new browser key by providing package name and put that key into main activity((String key = “key”). but when a typed in the text box it shows only typed text there is no auto-completion texts shown… please help….

  7. Sidra on October 18, 2013 at 2:43 pm

    your tutorials are just awesome . Thank you for providing solutions in simplest ways.

  8. chandu on December 24, 2013 at 11:13 am

    hi

    i want lod more values to autocomplete if i scroll down the items list like load more to list view

  9. Pratik Borole on December 26, 2013 at 1:17 pm

    Hey, thanks for this amazing tutorial. I was scouring the internet for a tut like this. But yours is the first one that actually WORKS!!! Many thanks again.

  10. Android on December 28, 2013 at 7:06 pm

    Hello George,

    I have a query, if you manage to find a little time please reply on the same.When i try to search using space the list of places just vanishes. Please explain how to avoid this.

    • deepak on November 28, 2014 at 3:30 pm

      I’m also stuck at the same problem. @Android, Were you able to solve this?

  11. Rohit Pawar on January 16, 2014 at 10:46 am

    Hey thanks a lot.. you saved my day,
    just need to create Places API key as “Create browser key”

    Also leave the Accept requests from these HTTP referers (web sites): blank so that it allows access to all referrers and include the key generated in your query URL.

    and copy that key and place it to line 109 in MainActivity.

    again thanks

  12. Rocco on February 13, 2014 at 5:41 am

    Hello everyone and thank you for this magnificent example.
    the strange thing is that if I enter a search consists of multiple words, the autocomplete does not open.
    example:
    if I use “via crotone” does not work
    while if I use “crotone” yes.

    What can be the problem?

    Thank you.

  13. shaun on August 27, 2014 at 3:40 pm

    How can i get the results of a particular city only?

  14. Sharmila Devi on October 24, 2014 at 12:37 pm

    Hi,I’m android newbie.In my android project I’m Using EditText for google map search location option.I want change the EditText into autocomplete text.This one is not working for me.I’m using Android (Place API)API key.please help me how to resolve it.

  15. Jon Inazio on November 25, 2014 at 2:10 pm

    Thanks for your tutorial. It has been very helpful :)

    • Rajesh on April 17, 2015 at 3:08 pm

      i want to use it same please help me

  16. Dave Deep on January 20, 2015 at 10:49 am

    thank you verymuch sir.. :*

  17. Thamaraiselvam on February 4, 2015 at 5:40 pm

    it is running but i cannot get auto complete !

    it is like normal textview ! please help me !

    i have internet connection and i run in all devices it is not working !

  18. Praful Patel on February 12, 2015 at 1:13 pm

    I want to this app with xml parser ..
    give me a code of xml parser ..

  19. Tushar Sircar on March 15, 2015 at 5:12 pm

    Sir,
    I managed to make it work but the place search is not very good.
    If I type the name of a mall in New Delhi I get 0 results and similarly 0 results for many common places.

    What should I do?

    • George Mathew on March 16, 2015 at 10:14 am

      Hi Tushar,

      Please check logcat to find the occurrence of any errors

  20. Manojkumar on April 2, 2015 at 3:04 pm

    Hai George Mathew,

    Please Help me,

    How can we fetch Data from ksoap webservice ,show in android Autocomplete textview search suggestion.

    fetching data is Working fine, showing webservice data in autocomplete textview is the Problem.

    Thanks

    • ChaoLun Cheng on April 30, 2015 at 11:34 am

      Hi Manojkumar ,

      I had the same problem too. The data had been download but the autocomplete textview did not show.

      You can add adapter.nofityDataSetChanged after you set adapter for autocomplete textview in MainActivity.

      This function can notify the adapter that something is changed.

      It’s works fine to me.

      Below is the modified code at MainActivity line 186.

      // Setting the adapter
      atvPlaces.setAdapter(adapter);
      synchronized (adapter){
      adapter.notifyDataSetChanged();
      }

      Thank you.

  21. Sathiya on May 12, 2015 at 12:10 pm

    HI thanks for such wonderful tutorial really help me. i have a issue with the autocomplete after selected i see the result like this, i have implemented this code in my app issue-this is what shows in the autocomplete textview-> {description=city,country}.

  22. Goutham on June 1, 2015 at 12:03 pm

    Hello Sir,

    I have a little problem with the autocompletetextview.

    Actually the thing is when i query something with a space in the autocompletetextview like (A S Rao) the program doesn’t show any result, if i avoid the spaces then it is fine. Can you please help me out with the space issue.

    Thanks
    Goutham

  23. surendra kumar sharma on June 24, 2015 at 3:23 pm

    how to dynamically fetch data from server for autocomplete textbox in android

    like we enter a in autocomplete txtbox
    then data from server
    ashish
    ashok
    alok etc.

    like we enter ka

    then data from server

    kamal
    kajal
    etc.

  24. triling on July 2, 2015 at 1:47 pm

    Hi

    I have generated API key, but not working.

    link:

    maps.googleapis.com/maps/api/place/autocomplete/json?input=h&types=geocode&sensor=false&AIzaSyCUV9OO_Fc21OaKpcIRiVo7vVjHwCjQUf8

    outcome
    {
    “error_message” : “This service requires an API key.”,
    “predictions” : [],
    “status” : “REQUEST_DENIED”
    }

    • Tarun Sharma on June 23, 2016 at 5:26 pm

      Have got solution for above prblm

    • Tarun Sharma on June 23, 2016 at 6:01 pm

      hi George, i got Http response but i am not getting in AutoCompleteText. so what to do,would you please guide me.
      I have ruin lots of times doing this

      i have Browser Key by enabling Google place API for Webservice.
      please mail me on tarun_9689@yahoo.com

  25. Ravi Gupta on July 3, 2015 at 11:22 pm

    AutoComplete is not showing any suggestion WHY? I think I should use Browser Key or Android Key

  26. Ravi Gupta on July 3, 2015 at 11:56 pm

    My autocomplete is not showing any data why is this so? should this is the case of Browser key or I should use Android Key.

    Sir don’t remove my comment instead please solve it

  27. TUSARKANT SAHOO on July 14, 2015 at 4:18 pm

    Added adapter.notifyDataSetChanged();
    after atvLocation.setAdapter(adapter); in onPostExecute() to respond to changes in SimpleAdapter

  28. harsh dashore on August 10, 2015 at 1:10 am

    how to get text from autocomplete in android i want to send this text to AsycTask so that on the basis of this parameter url can give suggetions data of autocompleteTextView

  29. Mahesh Saini on August 21, 2015 at 3:21 pm

    I download the code , and create the new browser key , but i did’t get anything ..can any one help me …

  30. keshav Gupta on September 1, 2015 at 5:01 pm

    Hi, your Example is nice but its not working for me .. i didn’t find any autocomplete textview…

    please help me

    thanks for your time..

  31. mohan on September 2, 2015 at 5:10 pm

    We need to add browser key or android key?

  32. nic on September 30, 2015 at 7:13 pm

    thanks for the tutorial sir. But I have question. How can I get the latlong of the address in autocomplete textview. I want to get latlng so I can put markers on map and draw route between two places.

    I really need to know it sir, pls help me.

  33. SAGARAM R VIJAYKUMAR on October 10, 2015 at 11:09 pm

    Thanks for your code… Really Awesome… Took time to integrate in to my project…. Following ur instructions really works….

  34. Nagesh on November 26, 2015 at 12:25 am

    Enable “Google Places API Web Service” API and give it a try. It worked for me.

    • Rupal bhanderi on March 17, 2016 at 12:57 pm

      still it is not working for me
      i was try all such things and i use same key for displaying root on google map for given place then it is working but for autocomplete no working
      so plz if u haevf any alternate code for same fuctionality plz mail me
      thank you so much in advance :)

  35. Avay Singh on January 15, 2016 at 11:59 pm

    Hello Friend,

    I am trying to run the above code in android kit kat 4.4 api level 19, but am not getting any auto suggestion. Could you please advise what can be the issue.

    Thanks,
    Avay

  36. Mustafa Raza on February 11, 2016 at 2:29 am

    Thanks you bro you solved my big problem it is working

  37. Tiya on May 31, 2016 at 11:35 am

    Can anyone help me to set a default value(current locayion of the user) for a Google places API auto complete textbox…help its urgent.

  38. sonnv1368 on June 10, 2016 at 4:19 pm

    Change input+”&”+types+”&”+sensor+”&”+key; ==> input+”&”+types+”&”+sensor+”&key=”+key;

    It is ok.

  39. Siddhi Jagtap on July 6, 2016 at 10:18 pm

    Hey,
    getMenuInflater().inflate(R.menu.activity_main, menu); shows and error with .menu highlighted red.It says it cannot resolve ‘menu’.Any help would be appreciated!
    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner