Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

geofire android to store and retrive locations and display it on map

I am developing an taxi application in android. I need to store retrieve and update location of my cabs and show it on maps using geofire. I have used firebase for authentication.

Need a complete tutorial for android geofire but can't find any

I have also seen SFVehicle example but didn't understand much

Any help would be appreciated!!!

like image 421
Vaibhav More Avatar asked Dec 04 '16 13:12

Vaibhav More


People also ask

How to use GeoFire in Android?

Including GeoFire in your Android project In order to use GeoFire in your project, you need to add the Firebase Android SDK. After that you can include GeoFire with one of the choices below. Add a dependency for GeoFire to your app's build. gradle file.

What is GeoFire?

If you want to use GeoFire in your Android application, see geofire-android . GeoFire is an open-source library for Java that allows you to store and query a set of keys based on their geographic location. At its heart, GeoFire simply stores locations with string keys.


2 Answers

Here is an example code for having a current location of driver

public class MainActivity extends AppCompatActivity implements
    OnMapReadyCallback, PermissionsListener {
// Variables needed to initialize a map
private MapboxMap mapboxMap;
private MapView mapView;
// Variables needed to handle location permissions
private PermissionsManager permissionsManager;
// Variables needed to add the location engine
private LocationEngine locationEngine;
private long DEFAULT_INTERVAL_IN_MILLISECONDS = 1000L;
private long DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS *1;
// Variables needed to listen to location updates
private MainActivityLocationCallback callback = new MainActivityLocationCallback(this);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Mapbox access token is configured here. This needs to be called either in your application
    // object or in the same activity which contains the mapview.
    Mapbox.getInstance(this, "");

    // This contains the MapView in XML and needs to be called after the access token is configured.
    setContentView(R.layout.activity_main);

    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(this);
}

@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
    this.mapboxMap = mapboxMap;

    mapboxMap.setStyle(Style.TRAFFIC_NIGHT,
            new Style.OnStyleLoaded() {
                @Override
                public void onStyleLoaded(@NonNull Style style) {
                    enableLocationComponent(style);
                }
            });
}

/**
 * Initialize the Maps SDK's LocationComponent
 */
@SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent(@NonNull Style loadedMapStyle) {
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {

        // Get an instance of the component
        LocationComponent locationComponent = mapboxMap.getLocationComponent();

        // Set the LocationComponent activation options
        LocationComponentActivationOptions locationComponentActivationOptions =
                LocationComponentActivationOptions.builder(this, loadedMapStyle)
                        .useDefaultLocationEngine(false)
                        .build();

        // Activate with the LocationComponentActivationOptions object
        locationComponent.activateLocationComponent(locationComponentActivationOptions);

        // Enable to make component visible
        locationComponent.setLocationComponentEnabled(true);

        // Set the component's camera mode
        locationComponent.setCameraMode(CameraMode.TRACKING);

        // Set the component's render mode
        locationComponent.setRenderMode(RenderMode.COMPASS);

        initLocationEngine();
    } else {
        permissionsManager = new PermissionsManager(this);
        permissionsManager.requestLocationPermissions(this);
    }
}

/**
 * Set up the LocationEngine and the parameters for querying the device's location
 */
@SuppressLint("MissingPermission")
private void initLocationEngine() {
    locationEngine = LocationEngineProvider.getBestLocationEngine(this);

    LocationEngineRequest request = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
            .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
            .setMaxWaitTime(DEFAULT_MAX_WAIT_TIME).build();

    locationEngine.requestLocationUpdates(request, callback, getMainLooper());
    locationEngine.getLastLocation(callback);
}

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

@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
    Toast.makeText(this, "Enable Location", Toast.LENGTH_LONG).show();
}

@Override
public void onPermissionResult(boolean granted) {
    if (granted) {
        if (mapboxMap.getStyle() != null) {
            enableLocationComponent(mapboxMap.getStyle());
        }
    } else {
        Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_LONG).show();
        finish();
    }
}

private static class MainActivityLocationCallback
        implements LocationEngineCallback<LocationEngineResult> {

    private final WeakReference<MainActivity> activityWeakReference;

    MainActivityLocationCallback(MainActivity activity) {
        this.activityWeakReference = new WeakReference<>(activity);
    }

    /**
     * The LocationEngineCallback interface's method which fires when the device's location has changed.
     *
     * @param result the LocationEngineResult object which has the last known location within it.
     */
    @Override
    public void onSuccess(LocationEngineResult result) {
        MainActivity activity = activityWeakReference.get();

        if (activity != null) {
            Location location = result.getLastLocation();

            if (location == null) {
                return;
            }
            FirebaseDatabase database = FirebaseDatabase.getInstance();
            String somi_id2 = "emp_samad";
            DatabaseReference myRef3 = database.getReference("current");
            GeoFire geoFire = new GeoFire(myRef3);
            geoFire.setLocation(somi_id2,new GeoLocation(location.getLatitude(),location.getLongitude()));

            Toast.makeText(activity,String.valueOf(location.getLatitude()+"\n"+String.valueOf(location.getLongitude())),Toast.LENGTH_SHORT).show();

            // Pass the new location to the Maps SDK's LocationComponent
            if (activity.mapboxMap != null && result.getLastLocation() != null) {
                activity.mapboxMap.getLocationComponent().forceLocationUpdate(result.getLastLocation());
            }
        }
    }

    /**
     * The LocationEngineCallback interface's method which fires when the device's location can not be captured
     *
     * @param exception the exception message
     */
    @Override
    public void onFailure(@NonNull Exception exception) {
        Log.d("LocationChangeActivity", exception.getLocalizedMessage());
        MainActivity activity = activityWeakReference.get();
        if (activity != null) {
            Toast.makeText(activity, exception.getLocalizedMessage(),
                    Toast.LENGTH_SHORT).show();
        }
    }
}

@Override
protected void onStart() {
    super.onStart();
    mapView.onStart();
}

@Override
protected void onResume() {
    super.onResume();
    mapView.onResume();
}

@Override
protected void onPause() {
    super.onPause();
    mapView.onPause();
}

@Override
protected void onStop() {
    super.onStop();
    mapView.onStop();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    // Prevent leaks
    if (locationEngine != null) {
        locationEngine.removeLocationUpdates(callback);
    }
    mapView.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    mapView.onLowMemory();
}
}

Now here is the code for showing him on map for realtime

    public class MainActivity extends AppCompatActivity  
      implements
        OnMapReadyCallback, PermissionsListener{

    private MapView mapView;
    private PermissionsManager permissionsManager;
    private MapboxMap mapboxMap;
    private GeoJsonSource geoJsonSource;
    private ValueAnimator animator;
    public static double pre_lat,pre_long;
    public static Marker marker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Mapbox.getInstance(this, "*YOUR_KEY*");
        setContentView(R.layout.activity_main);

        Mapbox.getInstance(this, "");

        mapView = findViewById(R.id.mapView);
        //fetchData process = new fetchData();
        // process.execute();
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(@NonNull final MapboxMap mapboxMap) {
                MainActivity.this.mapboxMap = mapboxMap;
                mapboxMap.setCameraPosition(new CameraPosition.Builder()
                        .zoom(19)
                        .target(new 
       LatLng(24.987029999999997,67.056585))
                        .build());
                mapboxMap.setStyle(Style.DARK,
                        new Style.OnStyleLoaded() {
                            @Override
                            public void onStyleLoaded(@NonNull Style style) {
                               // enableLocationComponent(style);
                                // Create an Icon object for the marker to use

                                FirebaseDatabase database = FirebaseDatabase.getInstance();
                                String somi_id2 = "emp_samad";
                                DatabaseReference myRef3 = database.getReference("current");
                                GeoFire geoFire = new GeoFire(myRef3);
                                GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(24.987043333333336, 67.05663333333334), 10);
                                geoFire.getLocation("emp_samad", new LocationCallback() {
                                    @Override
                                    public void onLocationResult(String key, GeoLocation location) {
                                        if (location != null) {
                                            pre_lat = location.latitude;
                                            pre_long = location.longitude;
//                                            Location prevLoc = new Location(location.latitude,location.longitude);
//                                            Location newLoc =  ;
//                                            float bearing = prevLoc.bearingTo(newLoc) ;
                                            marker = mapboxMap.addMarker(new MarkerOptions()
                                                    .position(new LatLng(pre_lat,pre_long))
                                                    .icon(IconFactory.getInstance(MainActivity.this).fromResource(R.drawable.marker)));
                                            System.out.println(String.format("The location for key %s is [%f,%f]", key, location.latitude, location.longitude));
                                        } else {
                                            System.out.println(String.format("There is no location for key %s in GeoFire", key));
                                        }
                                    }

                                    @Override
                                    public void onCancelled(DatabaseError databaseError) {

                                    }
                                });
                                geoQuery.addGeoQueryDataEventListener(new GeoQueryDataEventListener() {
                                    @Override
                                    public void onDataEntered(DataSnapshot dataSnapshot, GeoLocation location) {
                                        System.out.println(String.format("The location is [%f,%f]", location.latitude, location.longitude));
                                    }

                                    @Override
                                    public void onDataExited(DataSnapshot dataSnapshot) {

                                    }

                                    @Override
                                    public void onDataMoved(DataSnapshot dataSnapshot, GeoLocation location) {

                                    }

                                    @Override
                                    public void onDataChanged(DataSnapshot dataSnapshot, GeoLocation location) {
                                        double lat = pre_lat;
                                        double lon = pre_long;

                                        LatLng pre_latlng = new LatLng(lat,lon);
                                        LatLng washington = new LatLng(location.latitude,location.longitude);



                                        ValueAnimator markerAnimator = ValueAnimator.ofObject(new TypeEvaluator<LatLng>() {

                                            @Override
                                            public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
                                                return new LatLng(startValue.getLatitude() + (endValue.getLatitude() - startValue.getLatitude()) * fraction, startValue.getLongitude() + (endValue.getLongitude() - startValue.getLongitude()) * fraction);
                                            }

                                        }, new LatLng[]{pre_latlng, washington});

                                        markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                                            @Override
                                            public void onAnimationUpdate(ValueAnimator animation) {
                                                if (marker != null) {
                                                    marker.setPosition((LatLng) animation.getAnimatedValue());
                                                }
                                            }
                                        });

                                        markerAnimator.setDuration(7500);
                                        //markerAnimator.setRepeatCount(ValueAnimator.INFINITE);
                                        //markerAnimator.setRepeatMode(ValueAnimator.REVERSE);
                                        markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

                                        markerAnimator.start();

                                       /* if(marker!=null)
                                        {
                                            //marker.remove();
                                            //marker.setPosition(new LatLng(location.latitude,location.longitude));
                                        }
                                        System.out.println(String.format("The location is [%f,%f]", location.latitude, location.longitude));
*/

                                       }



                                    @Override
                                    public void onGeoQueryReady() {

                                    }

                                    @Override
                                    public void onGeoQueryError(DatabaseError error) {

                                    }
                                });
                            }
                        });
            }
        });
    }

    @SuppressWarnings( {"MissingPermission"})
    private void enableLocationComponent(@NonNull Style loadedMapStyle) {
// Check if permissions are enabled and if not request
        if (PermissionsManager.areLocationPermissionsGranted(this)) {

// Get an instance of the component
            LocationComponent locationComponent = mapboxMap.getLocationComponent();

// Activate with options
            locationComponent.activateLocationComponent(
                    LocationComponentActivationOptions.builder(this, loadedMapStyle).build());

// Enable to make component visible
            locationComponent.setLocationComponentEnabled(true);

// Set the component's camera mode
            locationComponent.setCameraMode(CameraMode.TRACKING);

// Set the component's render mode
            locationComponent.setRenderMode(RenderMode.COMPASS);
        } else {
            permissionsManager = new PermissionsManager(this);
            permissionsManager.requestLocationPermissions(this);
        }
    }

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

    @Override
    public void onExplanationNeeded(List<String> permissionsToExplain) {
        Toast.makeText(this, "Enable Location", Toast.LENGTH_LONG).show();
    }



    @Override
    public void onPermissionResult(boolean granted) {
        if (granted) {
            mapboxMap.getStyle(new Style.OnStyleLoaded() {
                @Override
                public void onStyleLoaded(@NonNull Style style) {
                   // enableLocationComponent(style);
                }
            });
        } else {
            Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_LONG).show();
            // finish();
        }
    }

    @Override
    @SuppressWarnings( {"MissingPermission"})
    public void onStart() {
        super.onStart();
        mapView.onStart();

    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
        mapView.onStop();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public void onMapReady(@NonNull MapboxMap mapboxMap) 
    {

    }


    }

what you have to use for this is to implement a geofire library Geofire implementation

implementation 'com.firebase:geofire-android:3.0.0'

I hope that this will help you alot

like image 167
Abdul Samad Avatar answered Sep 19 '22 14:09

Abdul Samad


I have created a library for Android, which provides geo-based firestore data to find the list of data within a given radius in KM / MILES.

It also gives the faster response in a single query read with the classification of the ADDED and REMOVED data in and from the query with real-time updates.

You can refer Geo-Firestore

It has well-documentation so you can easily develop the same.

like image 29
Chintak Patel Avatar answered Sep 17 '22 14:09

Chintak Patel