Geofencing not triggered when user exit that fence?(P.S.when it is already on same area it triiggered)

By sagar potdar

So Far :-

When user in same(under fence area) it gives notification “user enters in area” is ok.But same user leave fence area its not notified.

This is my code:-

public class MainActivity extends AppCompatActivity
    implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener,
    OnMapReadyCallback,
    GoogleMap.OnMapClickListener,
    GoogleMap.OnMarkerClickListener,
    ResultCallback<Status> {
private static final String TAG = MainActivity.class.getSimpleName();
private GoogleMap map;
private GoogleApiClient googleApiClient;
private Location lastLocation;
private TextView textLat, textLong;
private MapFragment mapFragment;
private static final String NOTIFICATION_MSG = "NOTIFICATION MSG";
// Create a Intent send by the notification
public static Intent makeNotificationIntent(Context context, String msg) {
    Intent intent = new Intent(context, MainActivity.class);
    intent.putExtra(NOTIFICATION_MSG, msg);
    return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textLat = (TextView) findViewById(R.id.lat);
    textLong = (TextView) findViewById(R.id.lon);
    // initialize GoogleMaps
    initGMaps();
    // create GoogleApiClient
    createGoogleApi();
}
// Create GoogleApiClient instance
private void createGoogleApi() {
    Log.d(TAG, "createGoogleApi()");
    if (googleApiClient == null) {
        googleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
}
@Override
protected void onStart() {
    super.onStart();
    // Call GoogleApiClient connection when starting the Activity
    googleApiClient.connect();
}
@Override
protected void onStop() {
    super.onStop();
    // Disconnect GoogleApiClient when stopping Activity
    googleApiClient.disconnect();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.geofence: {
            startGeofence();
            return true;
        }
        case R.id.clear: {
            clearGeofence();
            return true;
        }
    }
    return super.onOptionsItemSelected(item);
}
private final int REQ_PERMISSION = 999;
// Check for permission to access Location
private boolean checkPermission() {
    Log.d(TAG, "checkPermission()");
    // Ask for permission if it wasn't granted yet
    return (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED);
}
// Asks for permission
private void askPermission() {
    Log.d(TAG, "askPermission()");
    ActivityCompat.requestPermissions(
            this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
            REQ_PERMISSION
    );
}
// Verify user's response of the permission requested
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    Log.d(TAG, "onRequestPermissionsResult()");
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQ_PERMISSION: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted
                getLastKnownLocation();
            } else {
                // Permission denied
                permissionsDenied();
            }
            break;
        }
    }
}
// App cannot work without the permissions
private void permissionsDenied() {
    Log.w(TAG, "permissionsDenied()");
    // TODO close app and warn user
}
// Initialize GoogleMaps
private void initGMaps() {
    mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}
// Callback called when Map is ready
@Override
public void onMapReady(GoogleMap googleMap) {
    Log.d(TAG, "onMapReady()");
    map = googleMap;
    map.setOnMapClickListener(this);
    map.setOnMarkerClickListener(this);
}
@Override
public void onMapClick(LatLng latLng) {
    Log.d(TAG, "onMapClick(" + latLng + ")");
    //markerForGeofence(latLng);
}
@Override
public boolean onMarkerClick(Marker marker) {
    Log.d(TAG, "onMarkerClickListener: " + marker.getPosition());
    return false;
}
private LocationRequest locationRequest;
// Defined in mili seconds.
// This number in extremely low, and should be used only for debug
private final int UPDATE_INTERVAL = 1000;
private final int FASTEST_INTERVAL = 900;
// Start location Updates
private void startLocationUpdates() {
    Log.i(TAG, "startLocationUpdates()");
    locationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(UPDATE_INTERVAL)
            .setFastestInterval(FASTEST_INTERVAL);
    if (checkPermission())
        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
@Override
public void onLocationChanged(Location location) {
    Log.d(TAG, "onLocationChanged [" + location + "]");
    lastLocation = location;
    writeActualLocation(location);
}
// GoogleApiClient.ConnectionCallbacks connected
@Override
public void onConnected(@Nullable Bundle bundle) {
    Log.i(TAG, "onConnected()");
    getLastKnownLocation();
    recoverGeofenceMarker();
    startGeofence();
}
// GoogleApiClient.ConnectionCallbacks suspended
@Override
public void onConnectionSuspended(int i) {
    Log.w(TAG, "onConnectionSuspended()");
}
// GoogleApiClient.OnConnectionFailedListener fail
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    Log.w(TAG, "onConnectionFailed()");
}
// Get last known location
private void getLastKnownLocation() {
    Log.d(TAG, "getLastKnownLocation()");
    if (checkPermission()) {
        lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
        if (lastLocation != null) {
            Log.i(TAG, "LasKnown location. " +
                    "Long: " + lastLocation.getLongitude() +
                    " | Lat: " + lastLocation.getLatitude());
            writeLastLocation();
            startLocationUpdates();
        } else {
            Log.w(TAG, "No location retrieved yet");
            startLocationUpdates();
        }
    } else askPermission();
}
private void writeActualLocation(Location location) {
    textLat.setText("Lat: " + location.getLatitude());
    textLong.setText("Long: " + location.getLongitude());
    markerLocation(new LatLng(location.getLatitude(), location.getLongitude()));
}
private void writeLastLocation() {
    writeActualLocation(lastLocation);
}
private Marker locationMarker;
private void markerLocation(LatLng latLng) {
    Log.i(TAG, "markerLocation(" + latLng + ")");
    String title = latLng.latitude + ", " + latLng.longitude;
    MarkerOptions markerOptions = new MarkerOptions()
            .position(latLng)
            .title(title);
    if (map != null) {
        if (locationMarker != null)
            locationMarker.remove();
        locationMarker = map.addMarker(markerOptions);
        float zoom = 14f;
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, zoom);
        map.animateCamera(cameraUpdate);
    }
}
// Start Geofence creation process
private void startGeofence() {
    Log.i(TAG, "startGeofence()");
    Geofence geofence = createGeofence();
    GeofencingRequest geofenceRequest = createGeofenceRequest(geofence);
    addGeofence(geofenceRequest);
}
private static final long GEO_DURATION = 60 * 60 * 1000;
private static final String GEOFENCE_REQ_ID = "My Geofence";
private static final float GEOFENCE_RADIUS = 200.0f; // in meters
// Create a Geofence
private Geofence createGeofence() {
    Log.d(TAG, "createGeofence");
    return new Geofence.Builder()
            .setRequestId(GEOFENCE_REQ_ID)
            .setCircularRegion(18.478122, 73.890158, GEOFENCE_RADIUS)
            .setExpirationDuration(GEO_DURATION)
            .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
            .build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
    Log.d(TAG, "createGeofenceRequest");
    return new GeofencingRequest.Builder()
            .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
            .addGeofence(geofence)
            .build();
}
private PendingIntent geoFencePendingIntent;
private static final int GEOFENCE_REQ_CODE = 0;
private PendingIntent createGeofencePendingIntent() {
    Log.d(TAG, "createGeofencePendingIntent");
    if (geoFencePendingIntent != null)
        return geoFencePendingIntent;
    Intent intent = new Intent(this, GeofenceTrasitionService.class);
    return PendingIntent.getService(
            this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
// Add the created GeofenceRequest to the device's monitoring list
private void addGeofence(GeofencingRequest request) {
    Log.d(TAG, "addGeofence");
    if (checkPermission())
        LocationServices.GeofencingApi.addGeofences(
                googleApiClient,
                request,
                createGeofencePendingIntent()
        ).setResultCallback(this);
}
@Override
public void onResult(@NonNull Status status) {
    Log.i(TAG, "onResult: " + status);
    if (status.isSuccess()) {
        drawGeofence();
    } else {
        // inform about fail
    }
}
// Draw Geofence circle on GoogleMap
private Circle geoFenceLimits;
private void drawGeofence() {
    Log.d(TAG, "drawGeofence()");
    if (geoFenceLimits != null)
        geoFenceLimits.remove();
    CircleOptions circleOptions = new CircleOptions()
            .center(new LatLng(18.478122, 73.890158))
            .strokeColor(Color.argb(50, 70, 70, 70))
            .fillColor(Color.argb(100, 150, 150, 150))
            .radius(GEOFENCE_RADIUS);
    geoFenceLimits = map.addCircle(circleOptions);
}
private final String KEY_GEOFENCE_LAT = "GEOFENCE LATITUDE";
private final String KEY_GEOFENCE_LON = "GEOFENCE LONGITUDE";
// Saving GeoFence marker with prefs mng
private void saveGeofence() {
    Log.d(TAG, "saveGeofence()");
    SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    // editor.putLong(KEY_GEOFENCE_LAT, Double.doubleToRawLongBits(geoFenceMarker.getPosition().latitude));
    // editor.putLong(KEY_GEOFENCE_LON, Double.doubleToRawLongBits(geoFenceMarker.getPosition().longitude));
    editor.apply();
}
// Recovering last Geofence marker
private void recoverGeofenceMarker() {
    drawGeofence();
}
// Clear Geofence
private void clearGeofence() {
    Log.d(TAG, "clearGeofence()");
    LocationServices.GeofencingApi.removeGeofences(
            googleApiClient,
            createGeofencePendingIntent()
    ).setResultCallback(new ResultCallback<Status>() {
        @Override
        public void onResult(@NonNull Status status) {
            if (status.isSuccess()) {
                // remove drawing
                removeGeofenceDraw();
            }
        }
    });
}
private void removeGeofenceDraw() {
    Log.d(TAG, "removeGeofenceDraw()");
}

}

To get notification:-

public class GeofenceTrasitionService extends IntentService {
private static final String TAG = GeofenceTrasitionService.class.getSimpleName();
public static final int GEOFENCE_NOTIFICATION_ID = 0;
public GeofenceTrasitionService() {
    super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
    // Handling errors
    if ( geofencingEvent.hasError() ) {
        String errorMsg = getErrorString(geofencingEvent.getErrorCode() );
        Log.e( TAG, errorMsg );
        return;
    }
    int geoFenceTransition = geofencingEvent.getGeofenceTransition();
    // Check if the transition type is of interest
    if (geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT ) {
        // Get the geofence that were triggered
        List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
        String geofenceTransitionDetails = getGeofenceTrasitionDetails(geoFenceTransition, triggeringGeofences );
        // Send notification details as a String
        sendNotification( geofenceTransitionDetails );
    }
}
private String getGeofenceTrasitionDetails(int geoFenceTransition, List<Geofence> triggeringGeofences) {
    // get the ID of each geofence triggered
    ArrayList<String> triggeringGeofencesList = new ArrayList<>();
    for ( Geofence geofence : triggeringGeofences ) {
        triggeringGeofencesList.add( geofence.getRequestId() );
    }
    String status = null;
    if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT )
        status = "Exiting ";
    return status + TextUtils.join( ", ", triggeringGeofencesList);
}
private void sendNotification( String msg ) {
    Log.i(TAG, "sendNotification: " + msg );
    // Intent to start the main Activity
    Intent notificationIntent = MainActivity.makeNotificationIntent(
            getApplicationContext(), msg
    );
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    stackBuilder.addParentStack(MainActivity.class);
    stackBuilder.addNextIntent(notificationIntent);
    PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    // Creating and sending Notification
    NotificationManager notificatioMng =
            (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
    notificatioMng.notify(
            GEOFENCE_NOTIFICATION_ID,
            createNotification(msg, notificationPendingIntent));
}
// Create notification
private Notification createNotification(String msg, PendingIntent notificationPendingIntent) {
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
    notificationBuilder
            .setSmallIcon(R.drawable.ic_action_location)
            .setColor(Color.RED)
            .setContentTitle(msg)
            .setContentText("Geofence Notification!")
            .setContentIntent(notificationPendingIntent)
            .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
            .setAutoCancel(true);
    return notificationBuilder.build();
}
private static String getErrorString(int errorCode) {
    switch (errorCode) {
        case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
            return "GeoFence not available";
        case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
            return "Too many GeoFences";
        case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
            return "Too many pending intents";
        default:
            return "Unknown error.";
    }
}

}

As per tutorial i see:- there are 3 notification trigger
1.Enter 2.Dwell 3.Exit

I dont know how did i get notified when it leave the fence so far as in code i tried Exit.But no luck.

Source: Stack Overflow

    

Share it with your friends!

    Fatal error: Uncaught Exception: 12: REST API is deprecated for versions v2.1 and higher (12) thrown in /home/content/19/9652219/html/wp-content/plugins/seo-facebook-comments/facebook/base_facebook.php on line 1273