AutoCompleteTextView is not getting the suggestion

2019-03-02 02:47发布

This is my code to get the Places suggestions from Google Places API. But it is showing some error like "Cannot connect to Google Places API". I have given the proper error which I am getting at the bottom of this code.

I just need an AutoCompleteTextView to be populated with GeoLocations. For example, if the user types in "Deh", suggestions starting from Deh should appear right away,like, "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;
            }
        }

This is the error which I am getting.

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)

This is the updated Log error which I am getting.

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)

2条回答
We Are One
2楼-- · 2019-03-02 02:58

FYI:Avoid ActionBarActivity.Its deprecated .Try this Android – AutoCompleteTextView with Google Places Autocomplete API

查看更多
Animai°情兽
3楼-- · 2019-03-02 03:13

I just tested your code that builds the url, and it looks fine, so that is not the problem.

You're probably getting a timeout from a slow connection, try setting the timeout on your HttpURLConnection:

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

Also, note that if you haven't done so already, you will need to execute your network operation in a background thread, using an AsyncTask would be good for a short operation like this.

Edit:

I just ran a condensed version of your original code, and it worked just fine for me.

I used a Browser Key for the API key, and ran the autocomplete() method in an AsyncTask, and used "San Francisco" hard coded for the test.

Here is the full Activity class code that I used:

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

Here are the resulting logs:

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﹕ ============================================================
查看更多
登录 后发表回答