GeoFence triggering issue
I have setup geofence in my app, I am using IntetnService for the handle trigger event.
My issue is with trigger event many time.
Suppose i am at 1 Location inside Geofence, unfortunately some time enter or exit event trigger, Then i do like check the geoEvent.getTriggerdLocation() properties and check with geo fence radius,
if the trigger location to geo fence location distance greater then geofecen radius then an then i will release my exit event functionality,
but eventually geofence trigger event 2 3 km far even i already entered in fence and my above logic will fail. see snap
i want some solid fix for these.
Location is on with High priority
this will happening more when i will near to border of fence
Add geo fence list, as of now i am using only one fence.
mGeofenceList.add(new Geofence.Builder().setRequestId(String.valueOf(loGeoFenceModels.liGeoFenceID))
.setCircularRegion(loGeoFenceModels.ldGeoLatitude, loGeoFenceModels.ldGeoLongitude,
loGeoFenceModels.lfRadius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
PendidngIntentService
moGeofencePendingIntent = getGeofencePendingIntent();
LocationServices.GeofencingApi
.addGeofences(moLocationClient, getGeofencingRequest(), moGeofencePendingIntent)
.setResultCallback(this);
getGeofencingRequest() AND moGeofencePendingIntent
private GeofencingRequest getGeofencingRequest() {
return new GeofencingRequest.Builder().setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofences(mGeofenceList).build();
}
private PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (moGeofencePendingIntent != null) {
return moGeofencePendingIntent;
}
Intent intent = new Intent(moContext, GeofenceTransitionsIntentService.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent
// back when calling addgeoFences()
return PendingIntent.getService(moContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
GeofenceTransitionsIntentService.class
import java.util.ArrayList;
import java.util.List;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofenceStatusCodes;
import com.google.android.gms.location.GeofencingEvent;
import android.R.bool;
import android.app.IntentService;
import android.app.usage.UsageEvents.Event;
import android.content.Intent;
import android.database.Cursor;
import android.location.Location;
import android.text.TextUtils;
public class GeofenceTransitionsIntentService extends IntentService {
protected static final String TAG = "GeofenceTransitionsIS";
public GeofenceTransitionsIntentService() {
super(TAG); // use TAG to name the IntentService worker thread
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
private static String getGeofenceTransitionDetails(GeofencingEvent event) {
String transitionString = GeofenceStatusCodes.getStatusCodeString(event.getGeofenceTransition());
List<String> triggeringIDs = new ArrayList<String>();
for (Geofence geofence : event.getTriggeringGeofences()) {
triggeringIDs.add(geofence.getRequestId());
}
return String.format("%s: %s", transitionString, TextUtils.join(", ", triggeringIDs));
}
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
Log.i(TAG, "Geofencing Event : " + event);
if (event.hasError()) {
Log.i(TAG, "GeofencingEvent Error : " + event.getErrorCode());
return;
}
// Get the type of transition (entry or exit)
if (event.getGeofenceTransition() == Geofence.GEOFENCE_TRANSITION_ENTER) {
Log.i(TAG, "GeofencingEvent Enter");
}
if (event.getGeofenceTransition() == Geofence.GEOFENCE_TRANSITION_EXIT) {
Log.i(TAG, "GeofencingEvent Exit");
?
String description = getGeofenceTransitionDetails(event);
Log.i(TAG, "GeofencingEvent description : " + description);
}
}
Permissions
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.hardware.location.gps" />
i stuck in this issue since many days, please help to finish the issue.
Found one patch to avoid unwanted or dummy events.
you can get location on trigger time
Location loTriggerGeoFenceLocation = moEvent.getTriggeringLocation();
long ldAccuracy = loTriggerGeoFenceLocation.getAccuracy();
now store your geo fence location lat long and radius. not get trigger lat long and check the distance between trigger location and geo fence location lat long. if the distance are less then radius it should be the enter and is distance is more then radius it should be exit event
if (event.getGeofenceTransition() == Geofence.GEOFENCE_TRANSITION_EXIT) {
ldGeoLatLong = moSharedPreferenceManager.getGeoFenceTimeLocation();
Location loExistGeoFenceLocation = new Location("");
loExistGeoFenceLocation.setLatitude(ldGeoLatLong[0]);
loExistGeoFenceLocation.setLongitude(ldGeoLatLong[1]);
String lsRadius = moSharedPreferenceManager.getGeoFenceRadius();
float lfRadius = Float.parseFloat(lsRadius);
Log.i(TAG, "GeofencingEvent Exit");
float lfDistance = loTriggerGeoFenceLocation.distanceTo(loExistGeoFenceLocation);
if (lfDistance >= lfRadius && ldAccuracy <= 100f) {
moSharedPreferenceManager.setGeoFenceExit(true);
}
}