这是我从Google Places API获取商家推荐的代码。但是它显示了一些错误,例如"无法连接到Google Places API"。我已经在这段代码的底部给出了正确的错误。
我只需要使用GeoLocations填充AutoCompleteTextView。例如,如果用户键入" Deh",则应该立即显示从Deh开始的建议,例如," Dehradun,India"
public class MainActivity extends ActionBarActivity {
Button selectRoute;
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 = "My API Key";
AutoCompleteTextView home;
RadioButton yes, no;
Spinner location, facility;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog()
.penaltyDeath().build());
selectRoute = (Button) findViewById(R.id.button);
home = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
home.setAdapter(new GooglePlacesAutocompleteAdapter(this, R.layout.list));
home.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String str = (String) adapterView.getItemAtPosition(i);
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
});
home.setThreshold(1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
return super.onOptionsItemSelected(item);
}
//____________________________________________________________________________________
public static ArrayList autocomplete(String input) {
ArrayList resultList = null;
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
sb.append("?key=" + API_KEY);
sb.append("&input=" + URLEncoder.encode(input, "utf8"));
URL url = new URL(sb.toString());
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
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 {
JSONObject jsonObj = new JSONObject(jsonResults.toString());
JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");
resultList = new ArrayList(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 implements Filterable {
private ArrayList 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) {
resultList = autocomplete(constraint.toString());
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;
}
}
这是我得到的错误。
1691-1709/? E/Google Places Autocomplete﹕ Error connecting to Places API
java.net.ConnectException: failed to connect to maps.googleapis.com/74.125.130.95 (port 443): connect failed: ETIMEDOUT (Connection timed out)
at libcore.io.IoBridge.connect(IoBridge.java:114)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
at java.net.Socket.connect(Socket.java:843)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:131)
at com.android.okhttp.Connection.connect(Connection.java:101)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
at com.mycompany.com.shareadrive.MainActivity.autocomplete(MainActivity.java:143)
at com.mycompany.com.shareadrive.MainActivity$GooglePlacesAutocompleteAdapter$1.performFiltering(MainActivity.java:207)
at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
at libcore.io.Posix.connect(Native Method)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
at java.net.Socket.connect(Socket.java:843)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:131)
at com.android.okhttp.Connection.connect(Connection.java:101)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
at com.mycompany.com.shareadrive.MainActivity.autocomplete(MainActivity.java:143)
at com.mycompany.com.shareadrive.MainActivity$GooglePlacesAutocompleteAdapter$1.performFiltering(MainActivity.java:207)
at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
这是我得到的更新日志错误。
E/Google Places Autocomplete﹕ Error connecting to Places API
java.net.SocketTimeoutException: failed to connect to maps.googleapis.com/74.125.200.95 (port 443) after 15000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:159)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
at java.net.Socket.connect(Socket.java:843)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:131)
at com.android.okhttp.Connection.connect(Connection.java:101)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
at com.mycompany.com.shareadrive.MainActivity.autocomplete(MainActivity.java:136)
at com.mycompany.com.shareadrive.MainActivity$GooglePlacesAutocompleteAdapter$1.performFiltering(MainActivity.java:199)
at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
07-28 03:32:05.900 1785-1829/? W/Filter﹕ An exception occured during performFiltering()!
java.lang.NullPointerException
at com.mycompany.com.shareadrive.MainActivity$GooglePlacesAutocompleteAdapter$1.performFiltering(MainActivity.java:203)
at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
答案 0 :(得分:2)
我刚刚测试了构建网址的代码,看起来很好,所以这不是问题。
您可能会从慢速连接中获得超时,请尝试在HttpURLConnection上设置超时:
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(15000); //added
另外,请注意,如果您还没有这样做,则需要在后台线程中执行网络操作,使用AsyncTask可以很好地进行这样的短操作。
修改:
我刚刚运行了原始代码的精简版本,对我来说效果很好。
我使用浏览器密钥作为API密钥,并在AsyncTask中运行autocomplete()
方法,并使用&#34;旧金山&#34;硬编码为测试。
以下是我使用的完整Activity类代码:
public class MainActivity extends ActionBarActivity {
Button testButton;
TextView results;
private static final String LOG_TAG = "PlacesAPI";
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 = "my-api-key-here";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
results = (TextView) findViewById(R.id.result);
testButton = (Button) findViewById(R.id.button);
testButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new GetAutocompleteAsync().execute();
}
});
}
class GetAutocompleteAsync extends AsyncTask<String, String, ArrayList<String>>{
@Override
protected ArrayList<String> doInBackground(String... params) {
ArrayList<String> results = autocomplete("San Francisco");
return results;
}
@Override
protected void onPostExecute(ArrayList<String> resultArrayList) {
if (resultArrayList != null) {
results.setText(resultArrayList.toString());
}
}
}
public static ArrayList autocomplete(String input) {
ArrayList resultList = null;
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
sb.append("?key=" + API_KEY);
sb.append("&input=" + URLEncoder.encode(input, "utf8"));
URL url = new URL(sb.toString());
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
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 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 {
JSONObject jsonObj = new JSONObject(jsonResults.toString());
JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");
resultList = new ArrayList(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;
}
}
以下是生成的日志:
I/System.out﹕ San Francisco, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco, San Antonio, TX, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco International Airport, San Francisco, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco County, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco De La Espada, Espada Road, San Antonio, TX, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco, San Antonio, TX, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco International Airport, San Francisco, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco County, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco De La Espada, Espada Road, San Antonio, TX, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco, San Antonio, TX, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco International Airport, San Francisco, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco County, CA, United States
I/System.out﹕ ============================================================
I/System.out﹕ San Francisco De La Espada, Espada Road, San Antonio, TX, United States
I/System.out﹕ ============================================================
答案 1 :(得分:1)
仅供参考:避免 ActionBarActivity
。不推荐使用。请尝试Android – AutoCompleteTextView with Google Places Autocomplete API