Reputation: 330
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
Reputation: 37
The solution is adding googlePlaceApi to project in console.developers.google.com
Upvotes: -1
Reputation: 865
Go Google Console >> Api >> Enable Google Places API Web Service. See Solution
Upvotes: 2
Reputation: 1
Enable "Google Places API Web Service" API and give it a try. It worked for me.
Upvotes: 0
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
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
Reputation: 1526
I was fighting this issue yesterday, so it either
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')enableAutoManage(fragmentActivity, clientId, connectionCallback)
otherwise GoogleApiClient.blockingConnect()
or GoogleApiClient.connect()
calledFrankly 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
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
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