使用 Google Places Autocomplete API 时空间不工作

Posted

技术标签:

【中文标题】使用 Google Places Autocomplete API 时空间不工作【英文标题】:Spaces Not Working While Using Google Places Autocomplete API 【发布时间】:2013-11-16 23:12:51 【问题描述】:

当我在我的 android 应用中输入空格时,我的下拉菜单中不再显示任何结果。我怎样才能解决这个问题?我正在对输入进行编码,所以我不确定它为什么不起作用...

空格前:

空格后:

我查看了https://developers.google.com/places/documentation/autocomplete,但没有找到任何可以帮助我的东西。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
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.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=AIzaSyDcXFSC2I6ZqxQeAbUMFvJKMrA98217H9U";

        String input="";

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

        // place type to be searched
        String types = "types=(regions)";

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


【问题讨论】:

是的,输入中可以有(编码的)空格。当您发现问题时,您使用的是什么输入值? @pushbit 只有当我输入空格时,下拉菜单才会消失,我不再得到任何输出。 @GreekOphion 你找到这个问题的解决方案了吗,我也参考了同一个教程并遇到了同样的问题 【参考方案1】:

我刚刚尝试了一些搜索结果:

https://maps.googleapis.com/maps/api/place/autocomplete/json?input=123+43+Sweden&types=%28regions%29&sensor=false&key=AIzaSyDcXFSC2I6ZqxQeAbUMFvJKMrA98217H9U

URL 编码可能没有正确编码空间。如果您在 get 中有类似“123+”的内容,它应该会产生如上所示的有效结果。相反,您需要进行替换以将空格替换为 +。

input=input.replace(" ","+");

尝试在 URLEncoder 之后保留编码,但消除 + 被编码的任何风险。

HTH

【讨论】:

试过这个并没有改变任何东西。 您能否调试并确保您的 PlacesTask 中的 URL 看起来像 input=123+... 并调试 downloadUrl()HttpURLConnection 中的 URL 以确保它保持不变相同的格式? 编辑了我的答案以更新编码。基本上确保您发送到HttpURLConnection 的最终 URL 的输入地址使用+而不是空格。如果是这种情况,请尝试浏览器中的 URL 并查看您得到的预测。如果它适用于浏览器而不是应用程序,则AutoCompleteTextView 可能是问题所在。 @sturrockad Locatehttps://maps.googleapis.com/maps/api/place/autocomplete/json?input=Sector+24&types=geocode&sensor=false&key=AIzaSyDo_9RsCh1Hlw1LgNjEdyf3HPyZ76PE0eY 这是我的数据,但空间仍在停止建议 添加 adapter.notifyDataSetChanged();这对我有用【参考方案2】:

尝试添加

adapter.notifyDataSetChanged();

之后

atvPlaces.setAdapter(adapter);

【讨论】:

这修复了它。谢谢。【参考方案3】:

试试“。”而不是空间。你应该用 dot(.) 替换空格,如果它不起作用你应该像在 ubuntu 中一样尝试“\”。可能有用

【讨论】:

【参考方案4】:

尝试替换这一行

        input = "input=" + URLEncoder.encode(place[0], "utf-8");

通过

        input = "input=" + URLEncoder.encode(place[0]);

【讨论】:

【参考方案5】:

我喜欢一个解决方案,TextWatcher() 没有任何问题。

需要使用下面的代码 在下面的代码中,我没有覆盖“performFiltering”方法,我添加了它,我的自动完成文本框现在工作正常。

公共类 CustomAutoCompleteView 扩展 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);  
  

【讨论】:

以上是关于使用 Google Places Autocomplete API 时空间不工作的主要内容,如果未能解决你的问题,请参考以下文章

google.maps.places.Autocomplete 语言输出

使用 GooglePlacesAutocompleteWidget 时强制 flutter_google_places 仅显示城市

反应:Google Places API/ Places 详细信息

使用 google-places-api 的简单 html 页面的 ApiNotActivatedMapError

使用Javascript从Google Places搜索api获取纬度和经度

Google Places API,获取用户地址