Android Places Autocomplete задава шир. дълги граници

Използвам API за автоматично довършване на Google Places. Приложението ми има изглед на текст за автоматично довършване. Всичко работи добре, тъй като следвах примера тук.

Единственият проблем е, че задавам граници на LatLng спрямо тези на Mountain View.

  private static final LatLngBounds BOUNDS_MOUNTAIN_VIEW = new LatLngBounds(
        new LatLng(37.398160, -122.180831), new LatLng(37.430610, -121.972090));

Моят GoogleApiClient

 mGoogleApiClient = new GoogleApiClient.Builder(this)
             .addApi(Places.GEO_DATA_API)
             .build();

Когато се опитвам да въведа адрес в Ню Орлиънс, трябва да пиша много, което не е добро изживяване за всеки потребител, който е извън CA. Има ли по-добър начин да зададете границите на LatLng в зависимост от текущото местоположение, без да искате разрешение за местоположение или точна позиция на местоположението. Предполагам, че това не е ограничение на приложния програмен интерфейс (API) на Places, а само ограничените ми познания.

Благодаря предварително.


person Akhil Latta    schedule 18.06.2015    source източник


Отговори (2)


За съжаление не, ще ви е необходимо разрешение за местоположение, тъй като разрешението, което сте избрали във вашия манифест, определя точността на местоположението, върнато от клиента на Google API. Бих предложил да използвате ACCESS_COARSE_LOCATION, което е точно в рамките на 1 градска пресечка. Ето как динамично получих местоположението на потребителя и направих граница от прибл. Радиус от 5 мили около местоположението им.

public class PlacesSearchActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener,GoogleApiClient.ConnectionCallbacks, LocationListener {

    private String TAG = this.toString();
    protected GoogleApiClient mGoogleApiClient;
    private AutoCompleteTextView mAutocompleteView;
    private PlaceAutocompleteAdapter mAdapter;
    private LocationRequest mLocationRequest;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_places_search);

        // Construct a GoogleApiClient for the {@link Places#GEO_DATA_API} using AutoManage
        // functionality, which automatically sets up the API client to handle Activity lifecycle
        // events. If your activity does not extend FragmentActivity, make sure to call connect()
        // and disconnect() explicitly.
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .enableAutoManage(this, 0 /* clientId */, this)
                .addApi(Places.GEO_DATA_API)
                .addApi(LocationServices.API)
                .build();
        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_LOW_POWER)
                .setInterval(10 * 1000)        // 10 seconds, in milliseconds
                .setFastestInterval(1 * 1000); // 1 second, in milliseconds
        // Retrieve the AutoCompleteTextView that will display Place suggestions.
        mAutocompleteView = (AutoCompleteTextView)findViewById(R.id.autocomplete_places);
        // Register a listener that receives callbacks when a suggestion has been selected
        mAutocompleteView.setOnItemClickListener(mAutocompleteClickListener);
    }

    private void setBounds(Location location, int mDistanceInMeters ){
        double latRadian = Math.toRadians(location.getLatitude());

        double degLatKm = 110.574235;
        double degLongKm = 110.572833 * Math.cos(latRadian);
        double deltaLat = mDistanceInMeters / 1000.0 / degLatKm;
        double deltaLong = mDistanceInMeters / 1000.0 / degLongKm;

        double minLat = location.getLatitude() - deltaLat;
        double minLong = location.getLongitude() - deltaLong;
        double maxLat = location.getLatitude() + deltaLat;
        double maxLong = location.getLongitude() + deltaLong;

        Log.d(TAG,"Min: "+Double.toString(minLat)+","+Double.toString(minLong));
        Log.d(TAG,"Max: "+Double.toString(maxLat)+","+Double.toString(maxLong));

        // Set up the adapter that will retrieve suggestions from the Places Geo Data API that cover
        // the entire world.
        mAdapter = new PlaceAutocompleteAdapter(this, android.R.layout.simple_list_item_1,
                mGoogleApiClient, new LatLngBounds(new LatLng(minLat, minLong), new LatLng(maxLat, maxLong)), null);
        mAutocompleteView.setAdapter(mAdapter);
    }

    /**
     * Listener that handles selections from suggestions from the AutoCompleteTextView that
     * displays Place suggestions.
     * Gets the place id of the selected item and issues a request to the Places Geo Data API
     * to retrieve more details about the place.
     *
     * @see com.google.android.gms.location.places.GeoDataApi#getPlaceById(com.google.android.gms.common.api.GoogleApiClient,
     * String...)
     */
    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 PlaceAutocomplete object from which we
             read the place ID.
              */
            final PlaceAutocompleteAdapter.PlaceAutocomplete item = mAdapter.getItem(position);
            final String placeId = String.valueOf(item.placeId);
            Log.i(TAG, "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(mUpdatePlaceDetailsCallback);

            Toast.makeText(getApplicationContext(), "Clicked: " + item.description,
                    Toast.LENGTH_SHORT).show();
            Log.i(TAG, "Called getPlaceById to get Place details for " + item.placeId);
        }
    };

    /**
     * Callback for results from a Places Geo Data API query that shows the first place result in
     * the details view on screen.
     */
    private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
            = new ResultCallback<PlaceBuffer>() {
        @Override
        public void onResult(PlaceBuffer places) {
            if (!places.getStatus().isSuccess()) {
                // Request did not complete successfully
                Log.e(TAG, "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);

            Log.i(TAG, "Place details received: " + place.getName());

            places.release();
        }
    };

    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.e(TAG, "onConnectionFailed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());

        // TODO(Developer): Check error code and notify the user of error state and resolution.
        Toast.makeText(this,"Could not connect to Google API Client: Error " + connectionResult.getErrorCode(),Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLocationChanged(Location location) {
        setBounds(location,5500);
    }

    @Override
    public void onConnected(Bundle bundle) {
        Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

        if (location == null) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        } else {
            setBounds(location,5500);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }
}
person opt05    schedule 13.08.2015

Ако някой търси отговор, @opt05 не е напълно правилен, ако внедрим com.google.maps.android:android-maps-utils, можем просто да използваме SphericalUtil.ComputeOffset, за да получим

северен ъгъл

и а

южен ъгъл

и задайте граници с autocompletefilter.

пълен пример е:

 LatLng center = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
                LatLng northSide = SphericalUtil.computeOffset(center, 50000, 0);
                LatLng southSide = SphericalUtil.computeOffset(center, 50000, 180);

                LatLngBounds bounds = LatLngBounds.builder()
                                    .include(northSide)
                                    .include(southSide)
                                    .build();

                placeLocation.setBoundsBias(bounds);
                placeLocation.setFilter(typeFilter);

                placeDestination.setBoundsBias(bounds);
                placeDestination.setFilter(typeFilter);

тук placeLocation е AutoCompleteFragment, а методът на северната и южната страна computeOffset е

(център, където се намирате в момента или каквато и да е позиция, която искате да ограничите „Поставете радиус“ във вашия случай неговия изглед към планината)

(50 000 е разстоянието в метове)

(0 е за север, 90 е изток, 180 юг, 270 запад).

person forthelulx    schedule 09.02.2019
comment
ГРЕШКА: Неуспешно разрешаване: com.google.maps.android:android-maps-utils: - person Ghanshyam Bagul; 06.04.2020
comment
Намерих го зависимости {implementation 'com.google.maps.android:android-maps-utils:0.6.2' } - person Ghanshyam Bagul; 06.04.2020