使用AutoCompleteTextView搜索附近的地方

时间:2016-07-06 10:06:45

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

我想使用像https://www.google.co.in/maps/@12.9539974,77.6309395,11z?hl=en这样的AutoCompleteTextView显示附近地点的列表,并且还想显示像facebook CheckIn这样的地方的图标,当我搜索像ATM这样的单词然后显示附近的所有 ATM 在列表和图标中,是否可以在我的应用程序中实现?如果是,那怎么样?你能救我吗?

我的代码如下:

FindPlaces.java

public class FindPlaces extends AppCompatActivity implements LocationListener, GoogleApiClient.OnConnectionFailedListener {
    private GoogleApiClient mGoogleApiClient;
    private static final LatLngBounds BOUNDS_GREATER_SYDENY = new LatLngBounds(
            new LatLng(23.0396, 72.566), new LatLng(23.0396,
            72.566));//23.0396,72.566
    private AutoCompleteTextView mAutocompleteView;
    private Activity mActivity;
    private ImageView imgSearchClear;
    private String searchAddress = "";
    private PlaceAutocompleteAdapter mAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this, 0 /* clientId */, this)
                .addApi(Places.GEO_DATA_API).build();
        setContentView(R.layout.find_place);

        mActivity = FindPlaces.this;

        mAutocompleteView = (AutoCompleteTextView) findViewById(R.id.edtSearch);
        mAutocompleteView.setOnItemClickListener(mAutocompleteClickListener);
        imgSearchClear = (ImageView) findViewById(R.id.imgSearchClear);
        imgSearchClear.setVisibility(View.GONE);

        mAdapter = new PlaceAutocompleteAdapter(this, mGoogleApiClient,
                BOUNDS_GREATER_SYDENY, null);
        mAutocompleteView.setAdapter(mAdapter);
        mAutocompleteView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (WebInterface.isOnline(mActivity)) {
                    v.setFocusable(true);
                    v.setFocusableInTouchMode(true);
                } else {
                    v.setFocusable(false);
                    v.setFocusableInTouchMode(false);
                }
                return false;
            }
        });
        imgSearchClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAutocompleteView.setText("");
            }
        });
        mAutocompleteView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_SEARCH) {
//                    performSearch();
                    return true;
                }
                return false;
            }
        });

        mAutocompleteView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                if (WebInterface.isOnline(mActivity)) {
                    mAutocompleteView.setFocusable(true);
                    if (!mAutocompleteView.getText().toString().equals("")) {
                        imgSearchClear.setVisibility(View.VISIBLE);

                    } else {
                        imgSearchClear.setVisibility(View.GONE);
                    }
                } else {
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }

    @Override
    public void onLocationChanged(Location location) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    private AdapterView.OnItemClickListener mAutocompleteClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {
            /*
             * Retrieve the place ID of the selected item from the Adapter. The
             * adapter stores each Place suggestion in a AutocompletePrediction
             * from which we read the place ID and title.
             */
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getApplicationWindowToken(), 0);
            mAutocompleteView.clearFocus();

            final AutocompletePrediction item = mAdapter.getItem(position);
            final String placeId = item.getPlaceId();
            final CharSequence primaryText = item.getPrimaryText(null);

            Log.d("Autocomplete item item: ", item.getDescription());
            Log.d("Autocomplete item placeId: ", placeId);
            Log.d("Autocomplete item selected: ", primaryText + "");

            try {
                searchAddress = URLDecoder.decode(item.getDescription().toString(), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            /*
             * Issue a request to the Places Geo Data API to retrieve a Place
             * object with additional details about the place.
             */
            PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
                    .getPlaceById(mGoogleApiClient, placeId);
            placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
        }
    };
    private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback = new ResultCallback<PlaceBuffer>() {
        @Override
        public void onResult(PlaceBuffer places) {
            if (!places.getStatus().isSuccess()) {
                // Request did not complete successfully
                Log.d("Place query did not complete. Error: "
                        , places.getStatus().toString());
                places.release();
                return;
            }

            // Get the Place object from the buffer.
            final Place place = places.get(0);

            // Format details of the place for display and show it in a
            // TextView.

            Log.d("Full Address", place.getAddress().toString());

            String latlong = place.getLatLng().toString();
            String s = "";
            s = latlong.substring(latlong.indexOf("(") + 1);
            s = latlong.substring(0, latlong.indexOf(")"));

            String split[] = s.split(",");

            Log.d("Place details received: ", place.getName() + "");
//            mLocation = place.getName();
            places.release();
        }
    };
}

PlaceAutocompleteAdapter.java

public class PlaceAutocompleteAdapter
        extends ArrayAdapter<AutocompletePrediction> implements Filterable {

    private static final String TAG = "PlaceAutocompleteAdapter";
    private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
    /**
     * Current results returned by this adapter.
     */
    private ArrayList<AutocompletePrediction> mResultList;

    /**
     * Handles autocomplete requests.
     */
    private GoogleApiClient mGoogleApiClient;

    /**
     * The bounds used for Places Geo Data autocomplete API requests.
     */
    private LatLngBounds mBounds;

    /**
     * The autocomplete filter used to restrict queries to a specific set of place types.
     */
    private AutocompleteFilter mPlaceFilter;

    /**
     * Initializes with a resource for text rows and autocomplete query bounds.
     *
     * @see ArrayAdapter#ArrayAdapter(Context, int)
     */
    public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
                                    LatLngBounds bounds, AutocompleteFilter filter) {
        super(context, R.layout.map_data_row, android.R.id.text1);
        mGoogleApiClient = googleApiClient;
        mBounds = bounds;
        mPlaceFilter = filter;
    }

    /**
     * Sets the bounds for all subsequent queries.
     */
    public void setBounds(LatLngBounds bounds) {
        mBounds = bounds;
    }

    /**
     * Returns the number of results received in the last autocomplete query.
     */
    @Override
    public int getCount() {
        if (mResultList != null)
            return mResultList.size();
        else
            return 0;
    }

    /**
     * Returns an item from the last autocomplete query.
     */
    @Override
    public AutocompletePrediction getItem(int position) {
        return mResultList.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = super.getView(position, convertView, parent);

        // Sets the primary and secondary text for a row.
        // Note that getPrimaryText() and getSecondaryText() return a CharSequence that may contain
        // styling based on the given CharacterStyle.

        AutocompletePrediction item = getItem(position);

        TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
        TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
        textView1.setText(item.getPrimaryText(STYLE_BOLD));
        textView2.setText(item.getSecondaryText(STYLE_BOLD));

        return row;
    }

    /**
     * Returns the filter for the current set of autocomplete results.
     */
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                // Skip the autocomplete query if no constraints are given.
                if (constraint != null) {
                    // Query the autocomplete API for the (constraint) search string.
                    mResultList = getAutocomplete(constraint);
                    if (mResultList != null) {
                        // The API successfully returned results.
                        results.values = mResultList;
                        results.count = mResultList.size();
                    }
                }
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                if (results != null && results.count > 0) {
                    // The API returned at least one result, update the data.
                    notifyDataSetChanged();
                } else {
                    // The API did not return any results, invalidate the data set.
                    notifyDataSetInvalidated();
                }
            }

            @Override
            public CharSequence convertResultToString(Object resultValue) {
                // Override this method to display a readable result in the AutocompleteTextView
                // when clicked.
                if (resultValue instanceof AutocompletePrediction) {
                    return ((AutocompletePrediction) resultValue).getFullText(null);
                } else {
                    return super.convertResultToString(resultValue);
                }
            }
        };
    }
    private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
        if (mGoogleApiClient.isConnected()) {
            Log.d("Starting autocomplete query for: ", constraint + "");

            // Submit the query to the autocomplete API and retrieve a PendingResult that will
            // contain the results when the query completes.
            PendingResult<AutocompletePredictionBuffer> results =
                    Places.GeoDataApi
                            .getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
                                    mBounds, mPlaceFilter);

            // This method should have been called off the main UI thread. Block and wait for at most 60s
            // for a result from the API.
            AutocompletePredictionBuffer autocompletePredictions = results
                    .await(60, TimeUnit.SECONDS);

            // Confirm that the query completed successfully, otherwise return null
            final Status status = autocompletePredictions.getStatus();
            if (!status.isSuccess()) {
//                Toast.makeText(getContext(), "Error contacting API: " + status.toString(),Toast.LENGTH_SHORT).show();
                Log.d("Error getting autocomplete prediction API call: ", status.toString());
                autocompletePredictions.release();
                return null;
            }

            Log.d("Query completed. Received ", String.valueOf(autocompletePredictions.getCount()));

            // Freeze the results immutable representation that can be stored safely.
            return DataBufferUtils.freezeAndClose(autocompletePredictions);
        }
        Log.d(TAG, "Google API client is not connected for autocomplete query.");
        return null;
    }
}

1 个答案:

答案 0 :(得分:0)

我找到了通过https://maps.googleapis.com/maps/api/place/nearbysearch/json获取附近地点的解决方案?但它不是我想要的!!!我想在我的应用程序中实现像facebook checkin功能。