Android:Places SDK,无法搜索所有位置/搜索预测受到限制

时间:2019-12-29 21:44:37

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

我已经实现了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);
        }
    });

当我以编程方式实现它时,我不明白我在做什么错。您的帮助将不胜感激。预先感谢。

1 个答案:

答案 0 :(得分:0)

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

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

  2. .setLocationBias(bounds)您选择的矩形边界的角看起来很宽(经度相距非常远,大约为77公里),而较短(经度相对靠近,大约为27公里)。仔细检查这些内容是否确实反映出您想将搜索限制在的西南边界和东北边界。

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