GoogleSuggestClient.java revision 93bd2e70b8b08da1ec37fd0e990dac05551d2e90
149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert/*
249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * Copyright (C) 2010 The Android Open Source Project
349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert *
449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * you may not use this file except in compliance with the License.
649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * You may obtain a copy of the License at
749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert *
849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert *      http://www.apache.org/licenses/LICENSE-2.0
949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert *
1049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
1149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
1249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * See the License for the specific language governing permissions and
1449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * limitations under the License.
1549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert */
1649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
1749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertpackage com.android.quicksearchbox.google;
1849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
1949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport com.android.quicksearchbox.R;
2093bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringertimport com.android.quicksearchbox.Source;
2193bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringertimport com.android.quicksearchbox.SourceResult;
2293bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringertimport com.android.quicksearchbox.SuggestionCursor;
2349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
2449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.apache.http.HttpResponse;
2549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.apache.http.client.HttpClient;
2649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.apache.http.client.methods.HttpGet;
2749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.apache.http.impl.client.DefaultHttpClient;
2849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.apache.http.params.HttpParams;
2949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.apache.http.params.HttpProtocolParams;
3049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.apache.http.util.EntityUtils;
3149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.json.JSONArray;
3249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport org.json.JSONException;
3349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
3449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.content.ComponentName;
3549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.content.Context;
3649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.net.ConnectivityManager;
3749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.net.NetworkInfo;
3849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.text.TextUtils;
3949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.util.Log;
4049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
4149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport java.io.IOException;
4249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport java.io.UnsupportedEncodingException;
4349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport java.net.URLEncoder;
4449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport java.util.Locale;
4549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
4649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert/**
4749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * Use network-based Google Suggests to provide search suggestions.
4849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert */
4949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertpublic class GoogleSuggestClient implements GoogleClient {
5049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
5149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    private static final boolean DBG = false;
5249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    private static final String LOG_TAG = "GoogleSearch";
5349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
5449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    private static final String USER_AGENT = "Android/1.0";
5549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    private String mSuggestUri;
5649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    private static final int HTTP_TIMEOUT_MS = 1000;
5749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
5849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    // TODO: this should be defined somewhere
5949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    private static final String HTTP_TIMEOUT = "http.connection-manager.timeout";
6049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
6193bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    private final Context mContext;
6293bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    private final Source mSource;
6393bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    private final HttpClient mHttpClient;
6449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
6593bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    public GoogleSuggestClient(Context context, Source source) {
6649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        mContext = context;
6793bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert        mSource = source;
6849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        mHttpClient = new DefaultHttpClient();
6949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        HttpParams params = mHttpClient.getParams();
7049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        HttpProtocolParams.setUserAgent(params, USER_AGENT);
7149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        params.setLongParameter(HTTP_TIMEOUT, HTTP_TIMEOUT_MS);
7249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
7349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        // NOTE:  Do not look up the resource here;  Localization changes may not have completed
7449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        // yet (e.g. we may still be reading the SIM card).
7549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        mSuggestUri = null;
7649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    }
7749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
7849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    protected Context getContext() {
7949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        return mContext;
8049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    }
8149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
8249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    public ComponentName getIntentComponent() {
8349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        return new ComponentName(getContext(), GoogleSearch.class);
8449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    }
8549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
8693bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    public boolean isLocationAware() {
8793bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert        return false;
8893bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    }
8993bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert
9049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    /**
9149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert     * Queries for a given search term and returns a cursor containing
9249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert     * suggestions ordered by best match.
9349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert     */
9493bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    public SourceResult query(String query) {
9549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        if (TextUtils.isEmpty(query)) {
9649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            return null;
9749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        }
9849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        if (!isNetworkConnected()) {
9949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            Log.i(LOG_TAG, "Not connected to network.");
10049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            return null;
10149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        }
10249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        try {
10349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            query = URLEncoder.encode(query, "UTF-8");
10449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            // NOTE:  This code uses resources to optionally select the search Uri, based on the
10549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            // MCC value from the SIM.  iThe default string will most likely be fine.  It is
10649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            // paramerterized to accept info from the Locale, the language code is the first
10749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            // parameter (%1$s) and the country code is the second (%2$s).  This code *must*
10849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            // function in the same way as a similar lookup in
10949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            // com.android.browser.BrowserActivity#onCreate().  If you change
11049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            // either of these functions, change them both.  (The same is true for the underlying
11149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            // resource strings, which are stored in mcc-specific xml files.)
11249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            if (mSuggestUri == null) {
11349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                Locale l = Locale.getDefault();
11449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                String language = l.getLanguage();
11549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                String country = l.getCountry().toLowerCase();
11649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                // Chinese and Portuguese have two langauge variants.
11749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                if ("zh".equals(language)) {
11849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                    if ("cn".equals(country)) {
11949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                        language = "zh-CN";
12049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                    } else if ("tw".equals(country)) {
12149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                        language = "zh-TW";
12249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                    }
12349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                } else if ("pt".equals(language)) {
12449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                    if ("br".equals(country)) {
12549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                        language = "pt-BR";
12649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                    } else if ("pt".equals(country)) {
12749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                        language = "pt-PT";
12849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                    }
12949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                }
13049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                mSuggestUri = getContext().getResources().getString(R.string.google_suggest_base,
13149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                                                                    language,
13249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                                                                    country)
13349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                        + "json=true&q=";
13449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            }
13549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
13649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            String suggestUri = mSuggestUri + query;
13749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            if (DBG) Log.d(LOG_TAG, "Sending request: " + suggestUri);
13849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            HttpGet method = new HttpGet(suggestUri);
13949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            HttpResponse response = mHttpClient.execute(method);
14049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            if (response.getStatusLine().getStatusCode() == 200) {
14149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
14249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                /* Goto http://www.google.com/complete/search?json=true&q=foo
14349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                 * to see what the data format looks like. It's basically a json
14449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                 * array containing 4 other arrays. We only care about the middle
14549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                 * 2 which contain the suggestions and their popularity.
14649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                 */
14749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                JSONArray results = new JSONArray(EntityUtils.toString(response.getEntity()));
14849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                JSONArray suggestions = results.getJSONArray(1);
14949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                JSONArray popularity = results.getJSONArray(2);
15049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                if (DBG) Log.d(LOG_TAG, "Got " + suggestions.length() + " results");
15193bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert                return new GoogleSuggestCursor(mSource, query, suggestions, popularity);
15249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            } else {
15349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                if (DBG) Log.d(LOG_TAG, "Request failed " + response.getStatusLine());
15449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            }
15549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        } catch (UnsupportedEncodingException e) {
15649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            Log.w(LOG_TAG, "Error", e);
15749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        } catch (IOException e) {
15849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            Log.w(LOG_TAG, "Error", e);
15949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        } catch (JSONException e) {
16049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            Log.w(LOG_TAG, "Error", e);
16149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        }
16249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        return null;
16349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    }
16449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
16593bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    public SuggestionCursor refreshShortcut(String shortcutId, String oldExtraData) {
16649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        return null;
16749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    }
16849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
16949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    private boolean isNetworkConnected() {
17049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        NetworkInfo networkInfo = getActiveNetworkInfo();
17149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        return networkInfo != null && networkInfo.isConnected();
17249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    }
17349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
17449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    private NetworkInfo getActiveNetworkInfo() {
17549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        ConnectivityManager connectivity =
17649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
17749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        if (connectivity == null) {
17849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            return null;
17949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        }
18049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        return connectivity.getActiveNetworkInfo();
18149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    }
18249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
18393bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert    private static class GoogleSuggestCursor extends AbstractGoogleSourceResult {
18449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
18549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        /* Contains the actual suggestions */
18693bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert        private final JSONArray mSuggestions;
18749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
18849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        /* This contains the popularity of each suggestion
18949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert         * i.e. 165,000 results. It's not related to sorting.
19049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert         */
19193bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert        private final JSONArray mPopularity;
19293bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert
19393bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert        public GoogleSuggestCursor(Source source, String userQuery,
19493bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert                JSONArray suggestions, JSONArray popularity) {
19593bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert            super(source, userQuery);
19649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            mSuggestions = suggestions;
19749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            mPopularity = popularity;
19849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        }
19949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
20049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        @Override
20149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        public int getCount() {
20249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            return mSuggestions.length();
20349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        }
20449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
20549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        @Override
20693bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert        public String getSuggestionQuery() {
20749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            try {
20893bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert                return mSuggestions.getString(getPosition());
20949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            } catch (JSONException e) {
21049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                Log.w(LOG_TAG, "Error parsing response: " + e);
21149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert                return null;
21249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            }
21349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        }
21449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert
21549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        @Override
21693bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert        public String getSuggestionText2() {
21793bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert            try {
21893bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert                return mPopularity.getString(getPosition());
21993bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert            } catch (JSONException e) {
22093bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert                Log.w(LOG_TAG, "Error parsing response: " + e);
22193bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert                return null;
22249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert            }
22349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        }
22449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert    }
22549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert}
226