【问题标题】:Android: Places SDK, unable to search all the places / search predictions are limitedAndroid:Places SDK,无法搜索所有地点/搜索预测受限
【发布时间】:2019-12-29 21:44:37
【问题描述】:

我已实现 Places SDK 并使用 materialSearchBar 库以编程方式获取位置预测,如下面的代码所示。

    Places.initialize(MapsActivity.this, getString(R.string.google_maps_api));
    placesClient = Places.createClient(this);
    final AutocompleteSessionToken token = AutocompleteSessionToken.newInstance();

    materialSearchBar.setOnSearchActionListener(new MaterialSearchBar.OnSearchActionListener() {
        @Override
        public void onSearchStateChanged(boolean enabled) {

        }

        @Override
        public void onSearchConfirmed(CharSequence text) {
            startSearch(text.toString(), true, null, true);
        }

        @Override
        public void onButtonClicked(int buttonCode) {
            if (buttonCode == MaterialSearchBar.BUTTON_NAVIGATION) {
                if(drawerLayout.isDrawerOpen(GravityCompat.START)){

                }else{
                    drawerLayout.openDrawer(GravityCompat.START);
                }
            }else if (buttonCode == MaterialSearchBar.BUTTON_BACK) {
                materialSearchBar.disableSearch();
            }

        }
    });

    materialSearchBar.addTextChangeListener(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) {
            RectangularBounds bounds = RectangularBounds.newInstance(
                    new LatLng(24.856165, 66.669119),
                    new LatLng(25.125024, 67.899587));
            FindAutocompletePredictionsRequest predictionsRequest = FindAutocompletePredictionsRequest.builder()
                    .setCountry("PK")
                    .setTypeFilter(TypeFilter.ADDRESS)
                    .setLocationBias(bounds)
                    .setSessionToken(token)
                    .setQuery(s.toString())
                    .build();
            placesClient.findAutocompletePredictions(predictionsRequest).addOnCompleteListener(new OnCompleteListener<FindAutocompletePredictionsResponse>() {
                @Override
                public void onComplete(@NonNull Task<FindAutocompletePredictionsResponse> task) {
                    if (task.isSuccessful()) {
                        FindAutocompletePredictionsResponse predictionsResponse = task.getResult();
                        if (predictionsResponse != null) {
                            predictionList = predictionsResponse.getAutocompletePredictions();
                            List<String> suggestionsList = new ArrayList<>();
                            for (int i = 0; i < predictionList.size(); i++) {
                                AutocompletePrediction prediction = predictionList.get(i);
                                suggestionsList.add(prediction.getFullText(null).toString());
                            }
                            materialSearchBar.updateLastSuggestions(suggestionsList);
                            if (!materialSearchBar.isSuggestionsVisible()) {
                                materialSearchBar.showSuggestionsList();
                            }
                        }
                    } else {
                        Log.i("mytag", "prediction fetching task unsuccessful");
                    }
                }
            });
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });


    materialSearchBar.setSuggestionsClickListener(new SuggestionsAdapter.OnItemViewClickListener() {
        @Override
        public void OnItemClickListener(int position, View v) {
            if (position >= predictionList.size()) {
                return;
            }
            AutocompletePrediction selectedPrediction = predictionList.get(position);
            String suggestion = materialSearchBar.getLastSuggestions().get(position).toString();
            materialSearchBar.setText(suggestion);

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    materialSearchBar.clearSuggestions();
                }
            }, 1000);
            InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            if (imm != null)
                imm.hideSoftInputFromWindow(materialSearchBar.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
            final String placeId = selectedPrediction.getPlaceId();
            List<Place.Field> placeFields = Arrays.asList(Place.Field.LAT_LNG, Place.Field.NAME, Place.Field.ADDRESS,Place.Field.ADDRESS_COMPONENTS);

            FetchPlaceRequest fetchPlaceRequest = FetchPlaceRequest.builder(placeId, placeFields).build();
           // FetchPlaceRequest fetchPlaceRequest = FetchPlaceRequest.newInstance(placeId, placeFields);
            placesClient.fetchPlace(fetchPlaceRequest).addOnSuccessListener(new OnSuccessListener<FetchPlaceResponse>() {
                @Override
                public void onSuccess(FetchPlaceResponse fetchPlaceResponse) {
                    Place place = fetchPlaceResponse.getPlace();
                    Log.i("mytag", "Place found: " + place.getName());
                    Log.i("mytag", "Place found: " + place.getAddress());



                    //FETCH SELECTED PLACE LAT LNG
                    latLngOfPlace = place.getLatLng();
                    Log.i("mytag", "LAT: " + latLngOfPlace.latitude);
                    Log.i("mytag", "LNG: " + latLngOfPlace.longitude);
                    //ANIMATE CAMERA TO SELECTED LOCATION
                    if (latLngOfPlace != null) {
                       mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLngOfPlace, DEFAULT_ZOOM));
                    }
                   else{
                        Toast.makeText(MapsActivity.this, "unable to get location", Toast.LENGTH_SHORT).show();
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    if (e instanceof ApiException) {
                        ApiException apiException = (ApiException) e;
                        apiException.printStackTrace();
                        int statusCode = apiException.getStatusCode();
                        Log.i("mytag", "place not found: " + e.getMessage());
                        Log.i("mytag", "status code: " + statusCode);
                    }
                }
            });
        }

        @Override
        public void OnItemDeleteListener(int position, View v) {

        }
    });

问题是我无法搜索所有地方。它只预测一些地方而不是全部;通常可以使用谷歌地图搜索。 例如: 如果我尝试在我的城市搜索麦当劳,它只显示一个,而我们在我的城市有数十家麦当劳。

或任何其他餐厅或公共场所,它不会搜索其中任何一个。搜索非常有限。

但如果我使用 AutocompleteSupportFragment 实现 Places SDK,则搜索工作正常,如下所示:

  //INITIALIZE PLACES API
    Places.initialize(MapsActivity.this, getString(R.string.google_maps_api));
    placesClient = Places.createClient(this);

    // Initialize the AutocompleteSupportFragment.
    AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
            getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);

    // Specify the types of place data to return.
    autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME));

    // Set up a PlaceSelectionListener to handle the response.
    autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
        @Override
        public void onPlaceSelected(Place place) {
            // TODO: Get info about the selected place.
            Log.i("tag", "Place: " + place.getName() + ", " + place.getId());
        }

        @Override
        public void onError(Status status) {
            // TODO: Handle the error.
            Log.i("tag", "An error occurred: " + status);
        }
    });

我不明白我在以编程方式实现它时做错了什么。您的帮助将不胜感激。提前致谢。

【问题讨论】:

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


    【解决方案1】:

    您的程序化请求的两个参数可能会导致意外结果:

    1. .setTypeFilter(TypeFilter.ADDRESS) 仅返回地址,例如如果您的用户要输入收货地址。如果您希望您的搜索栏用于搜索诸如麦当劳之类的企业,您可能需要使用.setTypeFilter(TypeFilter.ESTABLISHMENT) 过滤类型Establishment。如果您不确定您的用户将使用哪种查询,请不要设置类型过滤器,因为这是一个可选参数。

    2. .setLocationBias(bounds) 您选择的矩形边界的角看起来相当宽(经度相距很远,大约 77 公里)和短(纬度相对靠近,大约 27 公里)。仔细检查这些是否真正反映了您想要限制搜索的西南和东北边界。

    这里是documentation for programmatic Place Autocomplete 供参考。

    【讨论】:

      猜你喜欢
      • 2013-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多