PlaceAutocomplete Widget on MapView Fragment

后端 未结 1 1572
有刺的猬
有刺的猬 2021-01-16 12:55

I am trying to create a mapview with a PlaceAutocomplete widget overlayed on it. The function of this view is to calculate the distance from my current location to the loca

1条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-16 13:12

    For all of you having the same issue, I have managed to implement the project I intended to, however I used a custom AutoCompleteTextView and attached it to the Google Places API. This enabled me to create a request and get back a response.

    Below is the code for all those brave souls who wish to create a call to the Google PlaceAutoComplete API, overlayed on a map.

    public class GeoFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    
        GoogleMap map;
        SupportMapFragment mapFragment;
        AutoCompleteTextView destination;
        GooglePlacesAutocompleteAdapter mAdapter;
        ListView listView;
        String dest;
    
        private LocationRequest lr;
        private GoogleApiClient apiClient;
        private static View view;
        private Location location;
        private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
        final String GOOGLE_KEY;
    
        double currentLatitude;
        double currentLongitude;
    
        private static final String[] LOCATION_PERMS={
                Manifest.permission.ACCESS_FINE_LOCATION
        };
    
        public GeoFragment() {
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
    
            if (!canAccessLocation() || !canAccessLocation()) {
                requestPermissions(LOCATION_PERMS, LOCATION_REQUEST);
            }
    
            buildGoogleApiClient();
    
            if (view != null) {
                ViewGroup parent = (ViewGroup) view.getParent();
                if (parent != null)
                    parent.removeView(view);
            }
    
            try {
                view = inflater.inflate(R.layout.layout_map, container, false);
    
                mapFragment = ((SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.mapView));
                destination = (AutoCompleteTextView) view.findViewById(R.id.destinationTextView);
    
                final CardView destinationCard = (CardView)view.findViewById(R.id._Cardview);
                final CardView placesCard = (CardView)view.findViewById(R.id._cardPlaces);
                mAdapter = new GooglePlacesAutocompleteAdapter(this.getActivity(), android.R.layout.simple_list_item_1);
    
                listView = (ListView) view.findViewById(R.id.placeList);
                listView.setAdapter(mAdapter);
                listView.setTextFilterEnabled(true);
    
                destination.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) {
                        placesCard.setVisibility(View.VISIBLE);
                        mAdapter.getFilter().filter(s.toString());
                    }
    
                    @Override
                    public void afterTextChanged(Editable s) {
                    }
                });
    
                listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView parent, View view, int position, long id) {
    
                        dest = (String) parent.getItemAtPosition(position);
                        destination.setText(dest);
                        dest = dest.replace(" ", "%20");
    
                        try {
                            SearchPlace(dest);
                        } catch (GooglePlayServicesNotAvailableException e) {
                            e.printStackTrace();
                        } catch (GooglePlayServicesRepairableException e) {
                            e.printStackTrace();
                        }
    
                        placesCard.setVisibility(View.INVISIBLE);
                        destinationCard.setVisibility(View.INVISIBLE);
                    }
                });
    
                map = mapFragment.getMap();
                map.getUiSettings().setAllGesturesEnabled(true);
                map.getUiSettings().setMyLocationButtonEnabled(true);
                map.setMyLocationEnabled(true);
                map.getUiSettings().setZoomControlsEnabled(false);
    
                map.animateCamera(CameraUpdateFactory.zoomIn());
                map.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);
                map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 19));
    
                MapsInitializer.initialize(this.getActivity());
            } catch (InflateException e) {
                Toast.makeText(getActivity(), "Problems inflating the view !",
                        Toast.LENGTH_LONG).show();
            } catch (NullPointerException e) {
                Log.e("GServices Error", e.toString());
            }
    
            return view;
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    
            switch(requestCode) {
    
                case LOCATION_REQUEST:
                    if (canAccessLocation()) {
                        callLocationPerms();
                    }
                    break;
            }
        }
    
        private void callLocationPerms() {
            Toast.makeText(getActivity().getApplicationContext(),
                    "We need your permission to access you current location", Toast.LENGTH_SHORT).show();
        }
    
        private boolean canAccessLocation() {
            return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
        }
    
        @TargetApi(Build.VERSION_CODES.M)
        private boolean hasPermission(String perm) {
            return(PackageManager.PERMISSION_GRANTED==getActivity().checkSelfPermission(perm));
        }
    
        protected synchronized void buildGoogleApiClient() {
            apiClient = new GoogleApiClient.Builder(getActivity().getApplicationContext())
                    .addApi(LocationServices.API)
                    .addApi(Places.GEO_DATA_API)
                    .addApi(Places.PLACE_DETECTION_API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }
    
        private boolean checkPlayServices() {
            int resultCode = GooglePlayServicesUtil
                    .isGooglePlayServicesAvailable(getActivity().getApplicationContext());
            if (resultCode != ConnectionResult.SUCCESS) {
                if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                    GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), PLAY_SERVICES_RESOLUTION_REQUEST).show();
                }
                return false;
            }
            return true;
        }
    
        public void getCoordinates(){
    
            location = LocationServices.FusedLocationApi.getLastLocation(apiClient);
    
            if (location != null) {
                currentLatitude = location.getLatitude();
                currentLongitude = location.getLongitude();
            }
        }
    
        @Override
        public void onLocationChanged(Location loc) {
    
            location = loc;
            getCoordinates();
    
            map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 19));
    
        }
    
        @Override
        public void onConnected(Bundle connectionHint) {
    
            if (location == null) {
                lr = LocationRequest.create();
                lr.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                lr.setInterval(1000);
                LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, lr, this);
    
            }
            //getCoordinates();
        }
    
        @Override
        public void onConnectionFailed(ConnectionResult result) {
            Log.i("Map Connection Failed", "Connection failed: ConnectionResult.getErrorCode() = "
                    + result.getErrorCode());
        }
    
        public void onConnectionSuspended(int arg0) {
            apiClient.connect();
        }
    
        public void SearchPlace(String place) throws GooglePlayServicesNotAvailableException, GooglePlayServicesRepairableException {
            PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
    
            //startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);
    
            callPlaces(currentLongitude, currentLatitude, place);
        }
    
        public void callPlaces(final double longitude, final double latitude, final String destination) {
            String tag_string_req = "req_places";
            String url =  "https://maps.googleapis.com/maps/api/directions/json?origin=" + latitude + "," + longitude + "&destination="+ destination +"&alternatives=false&mode=transit®ion=mt&key=" + getResources().getString(R.string.google_places_key);
    
            StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener() {
    
                @Override
                public void onResponse(String response) {
                    parsePlace(response);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("Error", "Registration Error: " + error.getMessage());
                    Toast.makeText(getActivity().getApplicationContext(),
                            error.getMessage(), Toast.LENGTH_LONG).show();
                }
            });
    
            AppController.getInstance().addToRequestQueue(strReq);
    
        }
    }
    

    Good luck and don't forget to vote-up please if this answer has helped you :)

    0 讨论(0)
提交回复
热议问题