PlaceAutocomplete Widget on MapView Fragment

岁酱吖の 提交于 2019-12-01 12:12:38

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&region=mt&key=" + getResources().getString(R.string.google_places_key);

        StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {

            @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 :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!