How to add markers on a map as users opens the act

2019-04-12 07:45发布

问题:

I have an activity in my app which has a Map in it and as users opens this activity from their devices, a marker is added showing their current location and then an inner Service class in which the code of updating the realtime location goes.

Here's my code:

        mDatabase.child(rID).addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                if (dataSnapshot.getValue() != null) {

                    Map<String, String> newAcceptedUser = (Map<String, String>) dataSnapshot.getValue();
                    pAccepted = newAcceptedUser.get("pName");
                    uidPAccepted = newAcceptedUser.get("pUrl");
                    String cLatS = newAcceptedUser.get("currentLat").trim();
                    currentLtAU = Double.parseDouble(cLatS);
                    String cLngS = newAcceptedUser.get("currentLng").trim();
                    currentLnAU = Double.parseDouble(cLngS);

                    Toast.makeText(getBaseContext(), pAccepted.trim() + " joined", Toast.LENGTH_LONG).show();

                    pMarker = mMap.addMarker(new MarkerOptions().position(new LatLng(currentLtAU, currentLnAU)).title(pAccepted.trim()));
                    venueMarker = mMap.addMarker(new MarkerOptions().position(new LatLng(Double.parseDouble(venueLat), Double.parseDouble(venueLng))).title("Play at " + venue.trim()).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
                    markersList.add(pMarker);
                    markersList.add(venueMarker);

                    ////get the latLngbuilder from the marker list
                    LatLngBounds.Builder builder = new LatLngBounds.Builder();
                    for (Marker m : markersList) {
                        builder.include(m.getPosition());
                    }

                    //Bounds padding here
                    int padding = 100;

                    //Create bounds here
                    LatLngBounds bounds = builder.build();

                    //Create camera with bounds
                    final CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);

                    startService(new Intent(getBaseContext(), ALocationService.class));

                    //Check map is loaded
                    mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
                        @Override
                        public void onMapLoaded() {
                            mMap.animateCamera(cu);
                            mMap.getUiSettings().setZoomControlsEnabled(true);
                            mMap.getUiSettings().setMapToolbarEnabled(true);
                            mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                            mMap.setMaxZoomPreference(19.0f);

                        }
                    });
                } else {
                    Snackbar snackbar = Snackbar
                            .make(coordinatorLayout, "Some error occurred. Please retry!", Snackbar.LENGTH_SHORT);
                    snackbar.show();
                }
            }
            ...
            ...
        });

Here's ALocationService.class:

public static class ALocationService extends Service {

        ...

        @Override
        public void onCreate() {
            super.onCreate();

            locationRequest = LocationRequest.create() //standard GMS LocationRequest
                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                    .setNumUpdates(1000)
                    .setInterval(1000);

            ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(getBaseContext());    
            subscription = locationProvider.getUpdatedLocation(locationRequest)
                    .subscribe(new Action1<Location>() {
                        @Override
                        public void call(Location location) {
                            currentLtAU = location.getLatitude();
                            currentLnAU = location.getLongitude();
                            if(pMarker!=null)
                            {
                                pMarker.remove();
                            }
                            pMarker = mMap.addMarker(new MarkerOptions().position(new LatLng(currentLtAU, currentLnAU)).title(pAccepted.trim()));
                            markersList.add(pMarker);
        }
        ...
    }

Here's onBackPressed():

@Override
    public void onBackPressed() {

            new AlertDialog.Builder(AcceptedRequest.this)
                    .setMessage("Are you sure you want to quit?")
                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {

                            Toast.makeText(getBaseContext(), pAccepted.trim() + " left", Toast.LENGTH_LONG).show();
                            markersList.remove(pMarker);
                            markersList.remove(venueMarker);
                            pMarker.remove();
                            venueMarker.remove();
                            stopService(new Intent(getBaseContext(), ALocationService.class));
                            subscription.unsubscribe();
                            finish();

                        }
                    })
                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            // do nothing
                        }
                    })
                    .show();
    }

Here's how data structure looks like:

-app
  -child
    -rID
      -uniqueId
        -key: value
        -key: value
        -key: value
      -uniqueId
        -key: value
        -key: value
        -key: value
      -uniqueId
        -key: value
        -key: value
        -key: value

The problem is that something weird is happening when different users are opening this activity from their devices. Like sometimes the venueMarker is getting renamed as pMarker or for one user 2-3 markers are getting added at once or users are unable to see updating realtime location of other users on the map and when pressing back button, this Toast.makeText(getBaseContext(), pAccepted.trim() + " left", Toast.LENGTH_LONG).show(); is showing name of other user instead of the user who has left.

It's all very complicated here. It'd be really helpful if you could suggest me some easy way of doing it or by improving my code and letting me know the issues!