3

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!

Hammad Nasir
  • 2,889
  • 7
  • 52
  • 133
  • 1
    Looks like you're at a point where adding lots and lots of log statements would help. Add lots of logging, run the code, and see what the logs show when problems arise. Add more logging as needed to hone in on the problems. – Daniel Nugent Jan 18 '17 at 04:08
  • @DanielNugent but there isn't any sort of runtime or compilation errors, it is just the problem with the logic I'm applying and that's why I asked for some easy way or some related tutorial. :| – Hammad Nasir Jan 18 '17 at 04:32
  • 1
    Yes, exactly. You need to use extra logging in order to figure out why things are going wrong when they do. Add logs in all of the important parts, and log values of important variables. You will see what a successful case looks like in the logs, and then you can compare that to the logs of a session where the problems occur. – Daniel Nugent Jan 18 '17 at 05:54
  • @DanielNugent I'm not questioning your skills and experience, but I'm unable to understand how **extra-logging** would help me here. It'd be great if you can describe your point in details. – Hammad Nasir Jan 18 '17 at 07:07
  • @DanielNugent please describe your point in details.. It'll be helpful then. – Hammad Nasir Jan 19 '17 at 01:50
  • 1
    Not much to it, I'm just telling you to debug your code with log statements. It's what I do to figure out complicated problems in a large code base, you should be able to figure out what's going wrong fairly quickly. Just keep adding more logging, run the code, and then look at the logs. Simple as that! – Daniel Nugent Jan 19 '17 at 02:11
  • 1
    are you adding markers in your service??? I think that is the problem. I remember when i made an app similar to this one. the purpose of my service is just to get the latlng values and other info for the markers then pass to my activity, the activity will be reliable to plot the markers. – Rashid Jan 20 '17 at 03:17
  • @SecretCoder Yeah, I'm adding updating the location and then adding the markers as per the updated location in the `ALocationService.class`. – Hammad Nasir Jan 24 '17 at 15:44
  • Add the structure of Firebase database you are using . I have made a similar app . – Rishabh Maurya Jan 26 '17 at 13:17
  • @RishabhMaurya please see the edited question.. – Hammad Nasir Jan 26 '17 at 13:25
  • @RishabhMaurya got something? – Hammad Nasir Jan 26 '17 at 14:51
  • @Hammad Nasir Why are you using service ? If you have firebase value event listener , use it to update the markers . It looks like service is causing the problem . – Rishabh Maurya Jan 26 '17 at 15:28
  • What about googlemaps clustering ? – Josef Korbel Jan 26 '17 at 23:27
  • hey @RishabhMaurya have a look at this: http://stackoverflow.com/q/42252017/6144372 I have modified the code and want some help – Hammad Nasir Feb 19 '17 at 19:05

0 Answers0