1

Hi im following this tutorial http://wptrafficanalyzer.in/blog/android-autocompletetextview-with-google-places-autocomplete-api/

MapsActivity.java

public class MapsActivity extends FragmentActivity {

private GoogleMap mMap; // Might be null if Google Play services APK is not available.
AutoCompleteTextView atvPlaces;
PlacesTask placesTask;
ParserTask parserTask;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    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());
        }

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

        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
        }
    });
    atvPlaces.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            atvPlaces.showDropDown();
            return false;
        }
    });
    setUpMapIfNeeded();
}
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=My Browser 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.main, menu);
    return true;
}
@Override
protected void onResume() {
    super.onResume();
    setUpMapIfNeeded();
}


public void onSearch(View view){
    String location = atvPlaces.getText().toString();

    List<Address> addressList = null;

    if(location!=null || location.equals("")){

        Geocoder geocoder = new Geocoder(this);
        try {
            addressList = geocoder.getFromLocationName(location, 1);
        } catch (IOException e) {
            e.printStackTrace();
        }

        Address address = addressList.get(0);
        LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
        mMap.addMarker(new MarkerOptions().position(latLng).title("Marker"));
        mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
    }
}

public void changeType(View view){
    if(mMap.getMapType() == GoogleMap.MAP_TYPE_NORMAL){
        mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
    }
    else{
        mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
    }
}

private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

private void setUpMap() {
    mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    mMap.setMyLocationEnabled(true);
}
}

CustomAutoCompleteTextView.java

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

PlaceJSONParser.java

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

activity_maps.xml

<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">

<LinearLayout
    android:layout_height="wrap_content"
    android:layout_width="wrap_content">

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

    <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Search"
    android:id="@+id/Bsearch"
    android:layout_gravity="right"
    android:onClick="onSearch"/>

    <Button
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Map Type"
        android:id="@+id/Btype"
        android:layout_gravity="right"
        android:onClick="changeType" />
</LinearLayout>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">


<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="387dp"
android:layout_height="626dp" android:id="@+id/map"
tools:context="com.example.group.taxisafe.MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment" />
</LinearLayout>

</LinearLayout>

My problem is, whenever i click on the autocomplete it throws JSON format. how to parse it and how I can automatically direct the user to that location if they click that autocomplete location.

user3802633
  • 347
  • 1
  • 4
  • 16
  • 1
    remove your key from code. do not show your private key to everyone. – Shvet Jun 24 '15 at 14:32
  • thanks. I already remove it. :) – user3802633 Jun 24 '15 at 14:42
  • You need to generate either server key or browser key. I not sure which key i have used in my application. Go to [Developer Console](https://console.developers.google.com) and register your application and make new key. – Shvet Jun 24 '15 at 14:54
  • I think you have put some IP when you generate your key. If you did, please remove it and make one without any IP. – Shvet Jun 24 '15 at 14:57
  • why? why so complex? why TextWatcher, AsyncTask, custom AutoCompleteTextView? do it as simple as this: http://stackoverflow.com/a/19860624/2252830 ... – pskink Jun 24 '15 at 15:07
  • this is what i put when i generate my key. B6:3A:35:16:D7:99:76:F0:42:AD:0A:28:8E:F0:A8:F5:9B:B1:07:04;com.example.group.taxisafe – user3802633 Jun 24 '15 at 15:12
  • @pskink Thank you for your suggestion. but it is different in autocomplete of a location in google map. – user3802633 Jun 24 '15 at 15:14
  • different? what do you mean? just call your web API in `runQuery()` method – pskink Jun 24 '15 at 15:14
  • @user3802633 in server key you dont need to put sha1 key. – Shvet Jun 24 '15 at 15:25
  • how do i generate a browser key? i generate that key through using my SHA1 and my package name. – user3802633 Jun 24 '15 at 15:36

1 Answers1

0

I tried constructing your URL and this is it : https://maps.googleapis.com/maps/api/place/autocomplete/json?input=London&types=geocode&sensor=false&key=Your_OLD_KEY ;)

When trying to open it in a browser just to test, I get :

{
 "error_message" : "This IP, site or mobile application is not authorized to use this API key. Request received from IP address XX.XX.XX.XX, with empty referer",
"predictions" : [],
"status" : "REQUEST_DENIED"
}

I understand that I am not allowed to used the Key since it I am not allowed to, so I ask you : did you update the allowed applications on your Google developer console ???? Did you create any key at all ?

  • yes. i created a browser key and i enable the Google Places API webservice, Google Places API for android and Google Maps API for android. I also tried the link that you gave and put my key at the last part but i also receive the same error like yours. – user3802633 Jun 24 '15 at 14:55
  • Then did you have restrictions on the browser key ? meaning did you modify the allowed users ?? – Mohamed Hamdaoui Jun 24 '15 at 15:01
  • I don't get what you are saying? can you explain where I can see that restrictions and how i can know that i modify the allowed users? – user3802633 Jun 24 '15 at 15:06
  • You go to where your key is on the Google developer console, and under the key there is a button : "Modify allowed referant" or something like that (it's in french for me) and try to see if you have set any specific IP ? – Mohamed Hamdaoui Jun 24 '15 at 15:11
  • It is Edit allowed referrers for me. But i don't put any IP address. This is what i put in the box to generate a key. B6:3A:35:16:D7:99:76:F0:42:AD:0A:28:8E:F0:A8:F5:9B:B1:07:04;com.example.group.taxisafe – user3802633 Jun 24 '15 at 15:16
  • That means only the application with that package name built on a machine with that SHA5 can use the key. And I'm not sure you're looking at the right key. Anyway, delete that line and retry. To make sure it's not IP related. – Mohamed Hamdaoui Jun 24 '15 at 15:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81434/discussion-between-mohamed-hamdaoui-and-user3802633). – Mohamed Hamdaoui Jun 24 '15 at 15:25
  • I already did it, :) it's my fault. it is in my key. :) Thanks @Mohamed. :) – user3802633 Jun 24 '15 at 16:47
  • I have another problem sir. I always got JSON format strings whenever i click at the autocomplete. do you know what is the problem of my code? – user3802633 Jun 24 '15 at 16:52