在Google Maps中阻止两个标记用于当前位置

时间:2018-06-20 14:40:05

标签: java android google-maps

我的MainActivity看起来像这样:-

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

}

正如您在方法addBoundaryToCurrentPosition()中看到的那样,在该“ // ****** //”(它是MainActivity的一部分)之下,我在当前位置的末尾设置了一个标记该方法应该每隔5000ms刷新一次。

此外,我有一个bottomNavigationView,它应该显示附近的地方。它的代码如下:-

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);


    }
}

}

在这种情况下,我创建了一个名为locate()的方法,该方法在切换结束时被调用。它会从MainActivity获取当前位置,并在清除地图后设置标记。

我面临的问题是,当我单击BottomNavView中的一个按钮时,起初只有一个用于当前位置的标记可见(由BottomNav标记),但是经过一段时间后,MainActivity的标记也开始显示。因此,显示了当前位置的两个标记。 我尝试创建一个处理程序,以在5000ms之后通过bottomNav删除标记,但是MainActivity的标记在经过随机时间后开始显示。

如何防止同时显示两个标记,同时确保至少一个标记始终可见?

1 个答案:

答案 0 :(得分:0)

首先,您需要将Marker变量名称更改为更具可读性的名称,因为它会使您感到困惑:

private Marker mCurrentPosition = null;
Marker marker;

当前职位是什么意思?是位置还是标记?什么是标记?我认为上面代码的更好的名字是:

private Marker mMarkerCurrentPosition = null;
private Marker mMarkerSelectedPlace;

第二,您使用BottomNavigationViewHelper.locate添加了一个标记,而没有删除之前的标记:

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

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

  ...
}

此外,您应该更改代码,以免通过将方法参数修改为以下内容来访问类外部的MainActivity变量:

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

}

最后,请勿使用GoogleMap.clear()清除标记。相反,请尝试始终一一删除所有添加到GoogleMap的标记。您可以通过始终将项目添加到列表中来实现。然后,您可以通过迭代列表来删除每个项目。例如:

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();
}