【问题标题】:AutoCompleteTextView is not getting the suggestions from Google Places APIAutoCompleteTextView 没有从 Google Places API 获得建议
【发布时间】:2015-07-27 14:21:33
【问题描述】:

这是我从 Google Places API 获取 Places 建议的代码。但它显示了一些错误,例如“无法连接到 Google Places API”。我已经给出了我在这段代码底部得到的正确错误。

我只需要一个 AutoCompleteTextView 来填充 GeoLocations。例如,如果用户输入“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)

【问题讨论】:

  • 请检查您的互联网连接,可能已关闭。

标签: android google-maps google-maps-android-api-2 google-places-api


【解决方案1】:

我刚刚测试了您构建 url 的代码,它看起来很好,所以这不是问题。

您可能因为连接缓慢而超时,请尝试在您的 HttpURLConnection 上设置超时:

conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(15000); //added

另外,请注意,如果您还没有这样做,您需要在后台线程中执行您的网络操作,使用 AsyncTask 将适合这样的短操作。

编辑:

我刚刚运行了您原始代码的精简版本,它对我来说效果很好。

我使用浏览器密钥作为 API 密钥,并在 AsyncTask 中运行 autocomplete() 方法,并使用硬编码的“旧金山”进行测试。

这是我使用的完整 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﹕ ============================================================

【讨论】:

  • InputStreamReader in = new InputStreamReader(conn.getInputStream());它说这一行有错误。你知道为什么吗?
  • URL url = new URL(sb.toString()); 中仍有错误conn = (HttpURLConnection) url.openConnection(); InputStreamReader in = new InputStreamReader(conn.getInputStream());和 resultList = autocomplete(constraint.toString());
  • @surya 你能在你的模拟器上浏览互联网吗?
  • 是的,我能做到。无论如何,如果代码正确,它应该可以在 Android 设备上正常工作。我在上面的行中有错误。我没有从 Google Places API 获得 JSON 结果。另外,您知道如何将 SHA 1 密钥添加到 google API 控制台。我创建了一个密钥并将其留空,以便任何 android 应用程序都可以使用它。可以吗?
  • @surya 这是场所 Web 服务 API,因此您应该使用服务器密钥。但是,我认为这不是您的问题,即使文档说 Android 密钥不起作用,但如果您将 sha1/package 字段保留为空白,它确实有效。明天我会测试你的代码,以确保它是正确的。
【解决方案2】:

仅供参考:避免ActionBarActivity。它已被弃用。试试这个Android – AutoCompleteTextView with Google Places Autocomplete API

【讨论】:

  • 我已经试过了,它没有按我的预期工作。 AutoCompleteTextView 根本没有得到建议。
  • @SuryaBadrinath 这怎么可能。您是否遵循了它的逐步方法?因为在这里它工作正常
  • 我想我正确地遵循了这些步骤。无论如何,我一定会再次尝试并回复。我还有一个疑问...... Emulator 是否支持 Map,因为我安装了 Google Play 服务并分别在 Studio 中添加了依赖项。知道是否还有其他事情要做吗?
猜你喜欢
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 2011-09-26
  • 2012-03-25
  • 2012-10-15
  • 1970-01-01
相关资源
最近更新 更多