Search code examples
geolocationandroid-geofence

How to get residence time in a geofence?


Simple question need simple answer. How can I track the residence time in a specific geofence. When I add geofence with Trigger on Enter, will I automatic receive a trigger when I leave that geofence. Basically I need to remember the time when I enter a geofence and when I leave that geofence so I can subtract leave-enter time and have my duration time. But I believe its not that easy to do that. So any other idea or advise how to solve that problem efficient ? Thanks


Solution

  • I found one solution for this problem. In order to determine the dwell time in a geofence i have to get the time when user trigger a geofence and then i use to calculate if user leave the geofence with this mathematical method

     Handler handler = new Handler();
        getCurrentLatLng();
        final Runnable myRunnable = new Runnable() {
            public void run() {
                GeofenceFinished myFinishedGeofence = db.getGeofenceFinishedByID("Finished" + id);
                if (!isUserInRegion(latitude, longitude, myLatLng.latitude, myLatLng.longitude, rd)
                        || myFinishedGeofence == null) {
                    String time = convertTime(endTime - startTime);
                    // get the finishedGeofence and set the duration of stay time
                    if (myFinishedGeofence != null)
                        setDurationOfStay("Finished" + id, time, getCurrentTime(System.currentTimeMillis()));
                    Toast.makeText(mContext, "Finish to determine duration of stay of " + myFinishedGeofence.getAddress(), Toast.LENGTH_SHORT).show();
                    handler.removeCallbacks(this);
                } else {
                    getCurrentLatLng();
                    endTime += Constants.DELAY;
                    handler.postDelayed(this, Constants.DELAY);
                }
            }
    
            private void setDurationOfStay(String geofenceid, String time, String endTime) {
                if (db == null) db = GeofenceDatabaseHelper.getInstance(mContext);
                if (!db.setDurationOfFinishedGeofence(geofenceid, time, endTime)) {
                    Log.i("setDurationOfStay", "fail");
                }
            }
        };
        handler.postDelayed(myRunnable, Constants.DELAY);
    
    private boolean isUserInRegion(double firstLat, double firstLog, double curLat, double curLog, float radius) {
        double distance = calculateDistance(firstLat, firstLog, curLat, curLog);
        return distance <= radius;
    }
    

    To calculate the distance of user and center of geofence, i need to convert the current latitude and longitude in meter, so i can calculate that with the parametic equation for circle

    So I use this approach from github

        // https://github.com/mgavaghan/geodesy
    private double calculateDistance(double firstLat, double firstLog, double curLat, double curLog) {
        GeodeticCalculator geoCalc = new GeodeticCalculator();
        Ellipsoid reference = Ellipsoid.WGS84;
        GlobalPosition pointA = new GlobalPosition(firstLat, firstLog, 0.0); // Point A
        GlobalPosition userPos = new GlobalPosition(curLat, curLog, 0.0); // Point B
        // Distance between Point A and Point B
        double distance = geoCalc.calculateGeodeticCurve(reference, userPos, pointA).getEllipsoidalDistance();
        return distance;
    }
    

    hope it helps someone :D