Android Geofence exit intent contains no data
Asked Answered
M

1

1

I'm using the relatively new version of the Geofence API in Google's Play Services. The issue (apart from outdated documentation) being that the received Intents (after a geofence exit) don't seem to contain any data.

  • I add a category myself and this category is successfully retrieved.
  • I added a serializeable extra too which is perfectly retrieved from the intent.

The above two arguments prove that the intent I am receiving is in fact the one I scheduled for a geofence transition.

What doesn't work.

The GeofenceEvent seems to return defaults for all methods. So I get;

  • false for hasError()
  • and -1 for getErrorCode()
  • getGeofenceTransition() returns -1
  • the list returned by getTriggeredGeofences() is empty

This seems to contradict the API documentation... getGeofenceTransition();

-1 if the intent specified in fromIntent(Intent) is not generated for a transition alert; Otherwise returns the GEOFENCE_TRANSITION_ flags value defined in Geofence.

with getErrorCode();

the error code specified in GeofenceStatusCodes or -1 if hasError() returns false.

and hasError();

true if an error triggered the intent specified in fromIntent(Intent), otherwise false

How I add the Geofence

// create fence
Geofence fence = new Geofence.Builder()
        .setRequestId(an_id)
        .setCircularRegion(lat, long, radius)
        .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
        .setExpirationDuration(240 * 60 * 1000)
        .build();

// create pendingintent
Intent launch = new Intent(this, same_class.class);
launch.putExtra(extra_object_key, extra_object);
launch.addCategory(category_name);

PendingIntent intent = PendingIntent.getService(
        getApplicationContext(),
        0, launch,
        PendingIntent.FLAG_UPDATE_CURRENT
);

// create add fence request
GeofencingRequest request = new GeofencingRequest.Builder()
        .addGeofence(fence)
        .build();

// add fence request
PendingResult<Status> result = LocationServices.GeofencingApi.addGeofences(googleApiClient,
        request, intent);

// we'll do this synchronous
Status status = result.await();
if (status.getStatusCode() != GeofenceStatusCodes.SUCCESS)
{
    Log.e(SERVICE_NAME, "Failed to add a geofence; " + status.getStatusMessage());
    return false;
}

How I receive the intent

protected void onHandleIntent(Intent intent)
{
    if (intent.hasCategory(category_name))
    {
        GeofencingEvent event = GeofencingEvent.fromIntent(intent);
        if (event.hasError())
        {
            Log.e(SERVICE_NAME, "Failed geofence intent, code: " + event.getErrorCode());
        }
        else
        {
            // checked 'event' here with debugger and prints for the stuff I wrote above

            switch (event.getGeofenceTransition())
            {
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    // NEVER REACHED
                    type extra_object =   (type)intent.getSerializableExtra(extra_object_key);
                    onGeofenceExit(extra_object);
                    break;
                default:
                    // ALWAYS END UP HERE
                    throw new AssertionError("Geofence events we didn't register for.");
            }
        }
    }
    else
    {
        throw new AssertionError("Received unexpected intent.");
    }
}

Connecting to play services

public void onCreate()
{
    super.onCreate();

    googleApiAvailable = false;
    GoogleApiClient.Builder  gApiBuilder = new GoogleApiClient.Builder(getApplicationContext());
    gApiBuilder.addApi(LocationServices.API);

    gApiBuilder.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks()
    {
        @Override
        public void onConnected(Bundle bundle)
        {
            googleApiAvailable = true;
        }

        @Override
        public void onConnectionSuspended(int i)
        {
            googleApiAvailable = false;
        }
    });

    gApiBuilder.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener()
    {
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult)
        {
            googleApiAvailable = false;
        }
    });

    googleApiClient = gApiBuilder.build();
}
Mcclenon answered 11/12, 2014 at 13:39 Comment(2)
No I never did. If you have news I'm still interested in it!Mcclenon
I have the same issue, when i pass Serializable Object through extras getGeofenceTransition returns -1, but when I pass some primitive variable it works . . .Fiedling
W
0

Where do you connect to googleApiClient? There should be

googleApiClient.connect();

and wait for onConnected or

googleApiClient.blockingConnect();

in you code but I can't see it. Post whole code.

Wedged answered 12/12, 2014 at 16:2 Comment(2)
I added the code I use to set up the play services. Before I do any geofencing I use the blockingConnect() method and I check the boolean.Mcclenon
it's there, my class is a lot bigger than posted here and I don't want to just copy paste a huge chunk of irrelevant details here. The whole thing is an intentservice and the onHandleIntent has 'handles' for different categories. The category that adds the fences has the connect too. I also check on errors after adding the fence, as you can see. This doesn't come up with errors.Mcclenon

© 2022 - 2024 — McMap. All rights reserved.