我的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的标记在经过随机时间后开始显示。
如何防止同时显示两个标记,同时确保至少一个标记始终可见?
答案 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();
}