Unaiza Khalid
Unaiza Khalid

Reputation: 330

Google Places autocomplete Android - Not working

I am new to Android App development. I followed this toturial to write a simple Google Places autocomplete Android App, but it does not return any suggestions when I start typing in the app; it gives NativeCrypto error in LogCat when I write anything in the autocomplete textview. Here is my code:

package com.example.newxyz; 

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.Toast;

public class GooglePlacesAutocompleteActivity extends Activity implements OnItemClickListener {
    private static final String LOG_TAG = "Google Places Autocomplete";
    private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
    private static final String TYPE_AUTOCOMPLETE = "/autocomplete";
    private static final String OUT_JSON = "/json";
    private static final String API_KEY = "AIzaSyAujQlZ1Jj64NAHMoynXjI253MVRzGW09w";
    private static final String True = "true";
    private static final String language = "en";

    AutoCompleteTextView autoCompView;
    @Override

   public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        autoCompView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);

        autoCompView.setAdapter(new GooglePlacesAutocompleteAdapter(this, R.layout.list_item));

        autoCompView.setOnItemClickListener(this);

    } 



    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

        String str = (String) adapterView.getItemAtPosition(position);
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
   }

    public static ArrayList<String> autocomplete(String input) {
        ArrayList<String> resultList = null;
        HttpURLConnection conn = null;
        StringBuilder jsonResults = new StringBuilder();
       try {
            StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
            sb.append("?sensor=" + True);
            sb.append("&key=" + API_KEY);
            sb.append("&language" + language);
            //sb.append("&components=country:gr");
            sb.append("&input=" + URLEncoder.encode(input, "utf8"));
            URL url = new URL(sb.toString());
            conn = (HttpURLConnection) url.openConnection();
            InputStreamReader in = new InputStreamReader(conn.getInputStream());


            // Load the results into a StringBuilder

           int read;
            char[] buff = new char[1024];
            while ((read = in.read(buff)) != -1) {
                jsonResults.append(buff, 0, read);
            }

        } catch (MalformedURLException e) {

            Log.e(LOG_TAG, "Error processing Places API URL", e);

            return resultList;
       } catch (IOException e) {
            Log.e(LOG_TAG, "Error connecting to Places API", e);
            return resultList;
        } finally {
            if (conn != null) {

                conn.disconnect();
            }
        }
        try {           
            // Create a JSON object hierarchy from the results
            JSONObject jsonObj = new JSONObject(jsonResults.toString());
            JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");
            // Extract the Place descriptions from the results
            resultList = new ArrayList<String>(predsJsonArray.length());
            for (int i = 0; i < predsJsonArray.length(); i++) {
                System.out.println(predsJsonArray.getJSONObject(i).getString("description"));
                System.out.println("============================================================");
                resultList.add(predsJsonArray.getJSONObject(i).getString("description"));
            }
        } catch (JSONException e) {
            Log.e(LOG_TAG, "Cannot process JSON results", e);
     }
        return resultList;
    }
   class GooglePlacesAutocompleteAdapter extends ArrayAdapter<String> implements Filterable {
        private ArrayList<String> resultList;
        public GooglePlacesAutocompleteAdapter(Context context, int textViewResourceId) {
            super(context, textViewResourceId);
        }
        @Override
        public int getCount() {
            return resultList.size();
        }
        @Override
        public String getItem(int index) {
            return resultList.get(index);
        }
        @Override
        public Filter getFilter() {
            Filter filter = new Filter() {
                @Override
                protected FilterResults performFiltering(CharSequence constraint) {
                    FilterResults filterResults = new FilterResults();
                    if (constraint != null) {
                        // Retrieve the autocomplete results.

                      resultList = autocomplete(constraint.toString());
                        // Assign the data to the FilterResults
                        filterResults.values = resultList;
                        filterResults.count = resultList.size();
                    }
                    return filterResults;
                }
                @Override

               protected void publishResults(CharSequence constraint, FilterResults results) {
                   if (results != null && results.count > 0) {
                        notifyDataSetChanged();
                    } else {
                        notifyDataSetInvalidated();
                    }
                }

            };
            return filter;
       }
    }
}

Here is my LogCat error:

05-04 13:16:27.705: E/NativeCrypto(9312): ssl=0x611c0a20 cert_verify_callback x509_store_ctx=0x62625940 arg=0x0
05-04 13:16:27.705: E/NativeCrypto(9312): ssl=0x611c0a20 cert_verify_callback calling verifyCertificateChain authMethod=ECDHE_RSA

Any help would be much appreciated. Thanks

Upvotes: 1

Views: 15571

Answers (8)

Mikhail
Mikhail

Reputation: 37

The solution is adding googlePlaceApi to project in console.developers.google.com

Upvotes: -1

Hardy Android
Hardy Android

Reputation: 865

Go Google Console >> Api >> Enable Google Places API Web Service. See Solution

Upvotes: 2

Nagesh
Nagesh

Reputation: 1

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

Upvotes: 0

Shikha
Shikha

Reputation: 3

I fond a solution there is nothing wrong with text watcher.

In the below code I didn't override "performFiltering" method. I added it and my auto complete text box now working fine.

public class CustomAutoCompleteView extends AutoCompleteTextView {  

public CustomAutoCompleteView(Context context) {  
    super(context);  
    // TODO Auto-generated constructor stub  
}  

public CustomAutoCompleteView(Context context, AttributeSet attrs) {  
    super(context, attrs);  
    // TODO Auto-generated constructor stub  
}  

public CustomAutoCompleteView(Context context, AttributeSet attrs,  
        int defStyle) {  
    super(context, attrs, defStyle);  
    // TODO Auto-generated constructor stub  
}  

@Override  
protected void performFiltering(final CharSequence text, final int keyCode) {  
    String filterText = "";  
    super.performFiltering(filterText, keyCode);  
}  
/** 
* After a selection, capture the new value and append to the existing 
* text 
*/  
@Override  
protected void replaceText(final CharSequence text) {  
    super.replaceText(text);  
}  

}  

Upvotes: 0

SolArabehety
SolArabehety

Reputation: 8616

In my case the problem was

"status":"REQUEST_DENIED",
"error_message":"This API project is not authorized to use this API. Please ensure that this API is activated "

And the solution was enable Google Places API Web Service in the Google Api Console.

Upvotes: 0

Ivan
Ivan

Reputation: 1526

I was fighting this issue yesterday, so it either

  • Wrong API_KEY (e.g. you might setup different prefix to debug version in build.gradle or used wrong SH1 or register to some other rather than 'Google Places API for Android')
  • If your GoogleApiClient not built with enableAutoManage(fragmentActivity, clientId, connectionCallback) otherwise GoogleApiClient.blockingConnect() or GoogleApiClient.connect() called

Frankly speaking, I'm not happy how #Google done this API. So odd, how to understand what's happened if you're getting code 9001, 9006, 9007 whatever?

Upvotes: 0

pushbit
pushbit

Reputation: 1268

Because you are using the Places API web service (as opposed to the Android service), you must enable the Google Places API Web Service API in the Google Developers Console.

Once you've got that working, if you would like to simplify your code and use a library that provides a GooglePlaceAutoComplete widget, check out Sprockets (I'm the developer). After setting it up with your API key, you could add a working Places API autocomplete to your layout with something like:

<net.sf.sprockets.widget.GooglePlaceAutoComplete
    android:id="@+id/place"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

Upvotes: 1

Hasmukh Barochiya
Hasmukh Barochiya

Reputation: 250

Please try to do something like this:

final StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
sb.append("?key=" + API_KEY);
sb.append("&input=" + URLEncoder.encode(input, "utf8"));
final URL url = new URL(sb.toString());
conn = (HttpURLConnection) url.openConnection();
final InputStreamReader in = new InputStreamReader(conn.getInputStream());

It is working in my case.

Upvotes: -1

Related Questions