简体   繁体   中英

Preventing two markers for current location in Google Maps

My MainActivity looks like this:-

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener, OnMapReadyCallback, LocationListener {

public static GoogleMap mMap;
public boolean flag = false;
public static  boolean markerAlready = false;
public static PlaceAutocompleteFragment placeAutoComplete;
private LocationManager mLocationManager = null;
private String provider = null;
Circle c;
private Marker mCurrentPosition = null;
Marker marker;
public static Location location;
CircleOptions mOptions;
public static Location l;
FancyButton button;


@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    button = findViewById(R.id.btnGuide);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this, "Opens guides's details!", Toast.LENGTH_SHORT).show();

        }
    });

    int perm = ContextCompat.checkSelfPermission(
            MainActivity.this,
            Manifest.permission.ACCESS_COARSE_LOCATION);

    if (perm == PackageManager.PERMISSION_GRANTED) {
        start();
        final LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
        if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
            buildAlertMessageNoGps();
        }


    } else {
        ActivityCompat.requestPermissions(
                MainActivity.this,
                new String[] {Manifest.permission.ACCESS_COARSE_LOCATION},
                44
        );
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {

    if (requestCode == 44) { //write request
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            start();
        }
    }
    else if (Build.VERSION.SDK_INT >= 23 && !shouldShowRequestPermissionRationale(permissions[0])) {
        Toast.makeText(MainActivity.this, "Go to Settings and Grant the permission to use this feature.", Toast.LENGTH_SHORT).show();
    }
}



public void start()
{
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingSearchView searchView = findViewById(R.id.floating_search_view);
    searchView.setSearchHint("");

    placeAutoComplete = (PlaceAutocompleteFragment) getFragmentManager().findFragmentById(R.id.place_autocomplete);
    Fragment a =  getFragmentManager().findFragmentById(R.id.place_autocomplete);
    a.setUserVisibleHint(false);
    placeAutoComplete.setOnPlaceSelectedListener(new PlaceSelectionListener() {
        @Override
        public void onPlaceSelected(Place place) {
            if (marker != null)
                marker.remove();
            flag = true;
            Log.d("Maps", "Place selected: " + place.getLatLng());
            marker = mMap.addMarker(new MarkerOptions().position(place.getLatLng()).title(place.getName().toString()).zIndex(800));
            mMap.moveCamera(CameraUpdateFactory.newLatLng(place.getLatLng()));
            mMap.animateCamera(CameraUpdateFactory.zoomIn());
            mMap.animateCamera(CameraUpdateFactory.zoomTo(13), 2000, null);

        }



        @Override
        public void onError(Status status) {
            Log.d("Maps", "An error occurred: " + status);
        }
    });

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            flag = false;
            mMap.clear();
            locateCurrentPosition();
            placeAutoComplete.setText(null);
        }
    });


    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();


    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

}

//region NavDrawer Activity
@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    if(id == R.id.emergency){
        List<String> HelpLineNumbers = new ArrayList<>();
        HelpLineNumbers.add("Women's Helpline");
        HelpLineNumbers.add("Police");
        HelpLineNumbers.add("Hospital");
        HelpLineNumbers.add("Fire Department");
        HelpLineNumbers.add("Ambulance");
        HelpLineNumbers.add("Men's Helpline");

        final CharSequence[] helpLine = HelpLineNumbers.toArray(new String[HelpLineNumbers.size()]);

        AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);
        mBuilder.setTitle("Helpline Numbers");

        mBuilder.setItems(helpLine, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                String selectedText = helpLine[i].toString();
            }
        });

        AlertDialog alertDialogObject = mBuilder.create();
        alertDialogObject.show();

    }

    List<String> HelpLineNumbers = new ArrayList<>();
    HelpLineNumbers.add("Women's Helpline");
    HelpLineNumbers.add("Police");
    HelpLineNumbers.add("Hospital");
    HelpLineNumbers.add("Fire Department");
    HelpLineNumbers.add("Ambulance");
    HelpLineNumbers.add("Men's Helpline");

    final CharSequence[] helpLine = HelpLineNumbers.toArray(new String[HelpLineNumbers.size()]);

    AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);
    mBuilder.setTitle("Helpline Numbers");

    mBuilder.setItems(helpLine, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            String selectedText = helpLine[i].toString();
        }
    });

    AlertDialog alertDialogObject = mBuilder.create();
    //Show the dialog
    alertDialogObject.show();

    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.myProfile) {
        // Handle the camera action

    } else if (id == R.id.myTrips) {

    } else if (id == R.id.fir) {

    } else if (id == R.id.logout) {

    } else if (id == R.id.contactus) {

    } else if (id == R.id.feedback) {

    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}



private void setupBottomNavigationView()
{
    Log.d("BottomNv", "setupBottomNavigationView: setting up botNavView");
    BottomNavigationViewEx bottomNavigationViewEx = findViewById(R.id.bnve);
    BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx);
    BottomNavigationViewHelper.enableNavigation(this,bottomNavigationViewEx);
}
//endregion





//region Maps Methods
public void onMapReady(GoogleMap googleMap) {
    LocationManager lm = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
    boolean gps_enabled = false;
    boolean network_enabled = false;

    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch(Exception ex) {
        Log.e("Error", "onMapReady: ");
    }

    try {
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch(Exception ex) {
        Log.e("Error", "onMapReady: " );
    }

    if(!gps_enabled && !network_enabled)
    {
        buildAlertMessageNoGps();
    }
    mMap = googleMap;

    mMap = googleMap;
    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
    if (isProviderAvailable() && (provider != null))
    {
        locateCurrentPosition();
    }
    setupBottomNavigationView();


}

public void locateCurrentPosition()
{

    int status = getPackageManager().checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION,
            getPackageName());

    if (status == PackageManager.PERMISSION_GRANTED) {

        location = mLocationManager.getLastKnownLocation(provider);
        updateWithNewLocation(location);

        //  mLocationManager.addGpsStatusListener(this);
        long minTime = 5000;// ms
        float minDist = 5.0f;// meter
        mLocationManager.requestLocationUpdates(provider, minTime, minDist, this);
        l=location;
        if(l != null)
            placeAutoComplete.setBoundsBias(new LatLngBounds(new LatLng(l.getLatitude(),l.getLongitude()),new LatLng(l.getLatitude()+2,l.getLongitude()+2)));
    }

}



private  void updateWithNewLocation(Location location) {

    if (location != null && provider != null) {
        double lng = location.getLongitude();
        double lat = location.getLatitude();

        if(!flag)
            addBoundaryToCurrentPosition(lat, lng);

        CameraPosition camPosition = new CameraPosition.Builder()
                .target(new LatLng(lat, lng)).zoom(12f).build();

        if (mMap != null && !flag)
            mMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(camPosition));
    } else {
        Log.d("Location error", "Something went wrong");
    }
}

//*****************************************************************//

private void addBoundaryToCurrentPosition(double lat, double lang) {
    Geocoder myLocation = new Geocoder(getApplicationContext(), Locale.getDefault());
    String addressStr = "";

    try {
        List<Address> myList = myLocation.getFromLocation(lat,lang, 1);
        Address address;
        address = (Address) myList.get(0);


        Log.d("LOCC", address.getAddressLine(0));

        addressStr += address.getAddressLine(0) ;

    } catch (IOException e) {
        e.printStackTrace();
    }


    MarkerOptions mMarkerOptions = new MarkerOptions();
    mMarkerOptions.position(new LatLng(lat, lang));
    mMarkerOptions.icon(BitmapDescriptorFactory
            .fromResource(R.drawable.ic_location));

    mMarkerOptions.anchor(0.5f, 0.5f);

    if( mOptions == null)
    {
        mOptions = new CircleOptions()
                .center(new LatLng(lat, lang)).radius(5000)
                .strokeColor(0x110000FF).strokeWidth(1).fillColor(0x110000FF);

        c = mMap.addCircle(mOptions);
    }
    else {
        c.remove();

        mOptions = new CircleOptions()
                .center(new LatLng(lat, lang)).radius(5000)
                .strokeColor(0x110000FF).strokeWidth(1).fillColor(0x110000FF);

        c = mMap.addCircle(mOptions);
    }

    if (mCurrentPosition != null)
        mCurrentPosition.remove();
          mCurrentPosition = mMap.addMarker(mMarkerOptions);
         mCurrentPosition.setTitle(addressStr);

}

private boolean isProviderAvailable() {
    mLocationManager = (LocationManager) getSystemService(
            Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_COARSE);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);

    provider = mLocationManager.getBestProvider(criteria, true);
    if (mLocationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        provider = LocationManager.NETWORK_PROVIDER;

        return true;
    }

    if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        provider = LocationManager.GPS_PROVIDER;
        return true;
    }

    if (provider != null) {
        return true;
    }
    return false;
}


@Override
public void onLocationChanged(Location location) {
    updateWithNewLocation(location);
}

@Override
public void onProviderDisabled(String provider) {

    updateWithNewLocation(null);
}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    switch (status) {
        case LocationProvider.OUT_OF_SERVICE:
            break;
        case LocationProvider.TEMPORARILY_UNAVAILABLE:
            break;
        case LocationProvider.AVAILABLE:
            break;
    }
}

public void buildAlertMessageNoGps()
{
    new MaterialDialog.Builder(this)
            .title("Location")
            .content("Enable Location")
            .positiveText("Enable GPS!")
            .negativeText("No, Thanks!")
            .cancelable(false)
            .positiveColor(Color.rgb(232,42,42))
            .negativeColor(Color.rgb(232,42,42))
            .onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    startActivity(myIntent);
                }
            })
            .onNegative(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    Toast.makeText(MainActivity.this, "Location Access Required!!", Toast.LENGTH_SHORT).show();
                    dialog.dismiss();
                }
            })
            .show();
}

//endregion

}

As you can see in the method addBoundaryToCurrentPosition(), below that "//******//" (it's a part of MainActivity), I've set a marker at current location towards the end of the method which is supposed to refresh after every 5000ms.

Moreover I have a bottomNavigationView which is supposed to show nearby places. It's code is as below:-

public class BottomNavigationViewHelper {


private static final String TAG = "BottomNavigationViewHel";
static Menu menu;
static MenuItem menuItem;
public static Location l;
public static void setupBottomNavigationView(BottomNavigationViewEx bottomNavigationViewEx)
{
    Log.d(TAG, "setupBottomNavigationView: setting up BottomNavView");
    bottomNavigationViewEx.enableAnimation(true);
    bottomNavigationViewEx.enableItemShiftingMode(false);
    bottomNavigationViewEx.enableShiftingMode(false);
    bottomNavigationViewEx.setTextVisibility(true);
    menu = bottomNavigationViewEx.getMenu();

}


public static void enableNavigation(final Context context, BottomNavigationViewEx view)
{
    view.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()){
                case R.id.ic_hospital:
                    menuItem = menu.getItem(0);
                    menuItem.setChecked(true);

                    String Hospital = "hospital";

                    Log.d("onClick", "Button is Clicked");
                    MainActivity.mMap.clear();
                    locate(MainActivity.location);
                    MainActivity.markerAlready = false;
                    MainActivity.placeAutoComplete.setText("Hospitals near me");
                    String urlhospital = getUrl(MainActivity.l.getLatitude(), MainActivity.l.getLongitude(), Hospital);
                    Object[] DataTransferhospital = new Object[2];
                    DataTransferhospital[0] = MainActivity.mMap;
                    DataTransferhospital[1] = urlhospital;
                    Log.d("onClick", urlhospital);
                    GetNearbyPlacesData getNearbyPlacesDatahospital = new GetNearbyPlacesData();
                    getNearbyPlacesDatahospital.execute(DataTransferhospital);
                    break;

                case R.id.ic_police:
                    menuItem = menu.getItem(1);
                    menuItem.setChecked(true);

                    String Police = "police";

                    Log.d("onClick", "Button is Clicked");
                    MainActivity.mMap.clear();
                    locate(MainActivity.location);
                    MainActivity.markerAlready = false;

                    MainActivity.placeAutoComplete.setText("Police Stations near me");

                    String urlpolice = getUrl(MainActivity.l.getLatitude(), MainActivity.l.getLongitude(), Police);
                    Object[] DataTransferpolice = new Object[2];
                    DataTransferpolice[0] = MainActivity.mMap;
                    DataTransferpolice[1] = urlpolice;
                    Log.d("onClick", urlpolice);
                    GetNearbyPlacesData getNearbyPlacesDatapolice = new GetNearbyPlacesData();
                    getNearbyPlacesDatapolice.execute(DataTransferpolice);

                    break;


                case R.id.ic_food:
                    menuItem = menu.getItem(2);
                    menuItem.setChecked(true);

                    String Restaurant = "restaurant";

                    Log.d("onClick", "Button is Clicked");
                    MainActivity.mMap.clear();
                    MainActivity.markerAlready = false;

                    MainActivity.placeAutoComplete.setText("Restaurants near me");
                    locate(MainActivity.location);

                    String urlrestaurant = getUrl(MainActivity.l.getLatitude(), MainActivity.l.getLongitude(), Restaurant);
                    Object[] DataTransferrestaurant = new Object[2];
                    DataTransferrestaurant[0] = MainActivity.mMap;
                    DataTransferrestaurant[1] = urlrestaurant;
                    Log.d("onClick", urlrestaurant);
                    GetNearbyPlacesData getNearbyPlacesDatarestaurant = new GetNearbyPlacesData();
                    getNearbyPlacesDatarestaurant.execute(DataTransferrestaurant);

                    break;

            }

            return false;
        }
    });
}

private static String getUrl(double latitude, double longitude, String nearbyPlace) {

    StringBuilder googlePlacesUrl = new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
    googlePlacesUrl.append("location=" + latitude + "," + longitude);
    googlePlacesUrl.append("&radius=" + 10000);
    googlePlacesUrl.append("&type=" + nearbyPlace);
    googlePlacesUrl.append("&sensor=true");
    googlePlacesUrl.append("&key=" + "AIzaSyATuUiZUkEc_UgHuqsBJa1oqaODI-3mLs0");
    Log.d("getUrl", googlePlacesUrl.toString());
    return (googlePlacesUrl.toString());
}

public static void locate(Location location) {
    if (location != null) {
        double lng = location.getLongitude();
        double lat = location.getLatitude();

        CameraPosition camPosition = new CameraPosition.Builder()
                .target(new LatLng(lat, lng)).zoom(12f).build();

        if (MainActivity.mMap != null) {
            MainActivity.mMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(camPosition));
        } else {
            Log.d("Location error", "Something went wrong");
        }


        final MarkerOptions mMarkerOptions = new MarkerOptions();
        mMarkerOptions.position(new LatLng(lat, lng));
        mMarkerOptions.icon(BitmapDescriptorFactory
                .fromResource(R.drawable.ic_location));

       final Marker m =  MainActivity.mMap.addMarker(mMarkerOptions);

        CircleOptions mOptions;
        final Circle c;


        mOptions = new CircleOptions()
                .center(new LatLng(lat, lng)).radius(5000)
                .strokeColor(0x110000FF).strokeWidth(1).fillColor(0x110000FF);

        c = MainActivity.mMap.addCircle(mOptions);


    }
}

}

In this I've created a method locate() , towards the end, which is called in switch cases. It fetches current location from MainActivity and sets marker after clearing the map.

The problem that I face is that when I click one of the buttons in BottomNavView, at first only one marker for current location is visible (that by BottomNav) but after some random time, marker by MainActivity also starts showing up. Hence two markers for current location show up. I've tried creating a handler to remove marker by bottomNav after 5000ms but marker of MainActivity starts showing after random amount of time.

How do I prevent two markers from showing up simultaneously while at the same time ensuring that at least on of the markers is visible at all times??

First , you need to change your Marker variable name to more a readable name because it makes you confuse:

private Marker mCurrentPosition = null;
Marker marker;

What current position means? is it location or marker? What is marker? I think the better name for the above code is following:

private Marker mMarkerCurrentPosition = null;
private Marker mMarkerSelectedPlace;

Second , you adding a marker with BottomNavigationViewHelper.locate without removing the previous marker:

public static void locate(Location location) {
  ...

  final Marker m =  MainActivity.mMap.addMarker(mMarkerOptions);

  ...
}

Furthermore, you should change your code so you can't access the MainActivity variable outside the class by modifying the method parameters to something like this:

public static void locate(GoogleMap map, Location location) {

}

Last , don't use GoogleMap.clear() to clear your markers. Instead, try to always removing all the markers added to the GoogleMap one by one. You can achieve it by always adding the item to a list. Then, you can remove each item by iterating the lists. For example:

List<Marker> markers;

// add 3 marker
markers.add(mMap.addMarker(mMarkerOptions));
markers.add(mMap.addMarker(mMarkerOptions));
markers.add(mMap.addMarker(mMarkerOptions));

// remove markers
for (Iterator<Marker> it = markers.listIterator(); it.hasNext(); ) {
  Marker marker = iter.next();
  // remove the marker from map
  marker.remove();
  // remove marker from list
  iter.remove();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM