从PlaceAutoComplete搜索城市名称会提供加密的城市名称

时间:2017-01-09 06:42:51

标签: android

我已经将Googleplaces的gradle从8.4.0更新到10.0.1

使用compile 'com.google.android.gms:play-services-places:10.0.1'。 它给出了我的预测结果:

E/PlaceAutocomplete: ChIJARFGZy6_wjsRQ-Oenb9DjYI

E/PlaceAutocomplete: ChIJCZRqkjTBwjsRtSBs09cqv5I

E/PlaceAutocomplete: ChIJSXAo8VjAwjsR8XBJRuCZo0c

E/PlaceAutocomplete: ChIJfxihRRy35zsRHL6ljyiIYKQ

E/PlaceAutocomplete: ChIJFZ6g4SXG5zsRdAbRQFugDUk

为“浦那”城市。

但是,在之前的gradle中: compile 'com.google.android.gms:play-services-places:8.4.0'。 它给出了正确的城市名称。

如何获得预期结果?

我从以下代码中获取城市名称:

if (mGoogleApiClient != null) {

        mAdapter = new PlaceAutoCompleteAdapter(getActivity(), android.R.layout.simple_list_item_1, mGoogleApiClient, BOUNDS_GREATER_SYDNEY, null);
        place_from.setAdapter(mAdapter);
        place_to.setAdapter(mAdapter);
        place_from.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                final PlaceAutoCompleteAdapter.PlaceAutocomplete item = mAdapter.getItem(position);
                final String placeId = String.valueOf(item.placeId);
                Log.i("", "Autocomplete item selected: " + item.description);
           /*
            * 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(new ResultCallback<PlaceBuffer>() {
                    @Override
                    public void onResult(PlaceBuffer places) {
                        if (!places.getStatus().isSuccess()) {
                            // Request did not complete successfully
                            Log.e("", "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);
                        start = place.getLatLng();
                    }
                });

            }
        });
     }
 });

并使用PlaceAutoCompleteAdapter

private static final String TAG = "PlaceAutocomplete";
/**
 * Handles autocomplete requests.
 */
private final GoogleApiClient mGoogleApiClient;
/**
 * The autocomplete filter used to restrict queries to a specific set of place types.
 */
private final AutocompleteFilter mPlaceFilter;
/**
 * Current results returned by this adapter.
 */
private ArrayList<PlaceAutocomplete> mResultList;
/**
 * The bounds used for Places Geo Data autocomplete API requests.
 */
private LatLngBounds mBounds;

/**
 * Initializes with a resource for text rows and autocomplete query bounds.
 *
 * @see ArrayAdapter#ArrayAdapter(Context, int)
 */
public PlaceAutoCompleteAdapter(Context context, int resource, GoogleApiClient googleApiClient,
                                LatLngBounds bounds, AutocompleteFilter filter) {
    super(context, resource);
    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() {
    return mResultList.size();
}

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

/**
 * Returns the filter for the current set of autocomplete results.
 */
@Override
public Filter getFilter() {
    Filter filter = 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();
            }
        }
    };
    return filter;
}

/**
 * Submits an autocomplete query to the Places Geo Data Autocomplete API.
 * <p/>
 * objects to store the Place ID and description that the API returns.
 * Returns an empty list if no results were found.
 * Returns null if the API client is not available or the query did not complete
 * successfully.
 * This method MUST be called off the main UI thread, as it will block until data is returned
 * from the API, which may include a network request.
 *
 * @param constraint Autocomplete query string
 * @return Results from the autocomplete API or null if the query was not successful.
 * @see Places#GEO_DATA_API#getAutocomplete(CharSequence)
 */
private ArrayList<PlaceAutocomplete> getAutocomplete(CharSequence constraint) {
    if (mGoogleApiClient.isConnected()) {
        Log.i(TAG, "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.            // Submit the query to the autocomplete API and retrieve a PendingResult that will

        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.e(TAG, "Error getting autocomplete prediction API call: " + status.getStatusMessage() + status.getStatus().getStatusMessage());
            autocompletePredictions.release();
            return null;
        }

        Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
                + " predictions.");

        // Copy the results into our own data structure, because we can't hold onto the buffer.
        // AutocompletePrediction objects encapsulate the API response (place ID and description).

        Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
        ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
        while (iterator.hasNext()) {
            AutocompletePrediction prediction = iterator.next();
            // Get the details of this prediction and copy it into a new PlaceAutocomplete object.
            resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
                    prediction.getPlaceId()));
        }

        // Release the buffer now that all data has been copied.
        autocompletePredictions.release();

        for (int i = 0; i < resultList.size(); i++) {
            Log.e(TAG, resultList.get(i).toString());

        }
        return resultList;
    }
    Log.e(TAG, "Google API client is not connected for autocomplete query.");
    return null;
}

/**
 * Holder for Places Geo Data Autocomplete API results.
 */
public class PlaceAutocomplete {

    public CharSequence placeId;
    public CharSequence description;

    PlaceAutocomplete(CharSequence placeId, CharSequence description) {
        this.placeId = placeId;
        this.description = description;
    }

    @Override
    public String toString() {
        return description.toString();
    }

}

}

2 个答案:

答案 0 :(得分:3)

此解决方案适合我

public class PlaceAutoCompleteAdapter
        extends ArrayAdapter<PlaceAutoCompleteAdapter.PlaceAutocomplete> implements Filterable {

    private static final String TAG = "PlaceAutocomplete";
    /**
     * Current results returned by this adapter.
     */
    private ArrayList<PlaceAutocomplete> mResultList;

    /**
     * Handles autocomplete requests.
     */
    private final 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 final AutocompleteFilter mPlaceFilter;

    /**
     * Initializes with a resource for text rows and autocomplete query bounds.
     *
     * @see ArrayAdapter#ArrayAdapter(Context, int)
     */
    public PlaceAutoCompleteAdapter(Context context, int resource, GoogleApiClient googleApiClient,
                                    LatLngBounds bounds, AutocompleteFilter filter) {
        super(context, resource);
        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() {
        return mResultList.size();
    }

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

    /**
     * Returns the filter for the current set of autocomplete results.
     */
    @Override
    public Filter getFilter() {
        Filter filter = 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();
                }
            }
        };
        return filter;
    }

    /**
     * Submits an autocomplete query to the Places Geo Data Autocomplete API.
     * <p/>
     * objects to store the Place ID and description that the API returns.
     * Returns an empty list if no results were found.
     * Returns null if the API client is not available or the query did not complete
     * successfully.
     * This method MUST be called off the main UI thread, as it will block until data is returned
     * from the API, which may include a network request.
     *
     * @param constraint Autocomplete query string
     * @return Results from the autocomplete API or null if the query was not successful.
     * @see Places#GEO_DATA_API#getAutocomplete(CharSequence)
     */
    private ArrayList<PlaceAutocomplete> getAutocomplete(CharSequence constraint) {
        if (mGoogleApiClient.isConnected()) {
            Log.i(TAG, "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.            // Submit the query to the autocomplete API and retrieve a PendingResult that will

            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.e(TAG, "Error getting autocomplete prediction API call: " + status.getStatusMessage()+status.getStatus().getStatusMessage());
                autocompletePredictions.release();
                return null;
            }

            Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
                    + " predictions.");

            // Copy the results into our own data structure, because we can't hold onto the buffer.
            // AutocompletePrediction objects encapsulate the API response (place ID and description).

            Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
            ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
            while (iterator.hasNext()) {
                AutocompletePrediction prediction = iterator.next();
                // Get the details of this prediction and copy it into a new PlaceAutocomplete object.
                resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
                        prediction.getDescription()));
            }

            // Release the buffer now that all data has been copied.
            autocompletePredictions.release();

            return resultList;
        }
        Log.e(TAG, "Google API client is not connected for autocomplete query.");
        return null;
    }

    /**
     * Holder for Places Geo Data Autocomplete API results.
     */
    public class PlaceAutocomplete {

        public CharSequence placeId;
        public CharSequence description;

        PlaceAutocomplete(CharSequence placeId, CharSequence description) {
            this.placeId = placeId;
            this.description = description;
        }

        @Override
        public String toString() {
            return description.toString();
        }


    }

}

答案 1 :(得分:0)

试试这个:

Places.GeoDataApi.getPlaceById(mGoogleApiClient, placeId)
    .setResultCallback(new ResultCallback<PlaceBuffer>() {
  @Override
  public void onResult(PlaceBuffer places) {
    if (places.getStatus().isSuccess() && places.getCount() > 0) {
      final Place myPlace = places.get(0);
      Log.i(TAG, "Place found: " + myPlace.getName());
    } else {
      Log.e(TAG, "Place not found");
    }
    places.release();
  }
});

Reference