Android BroadcastReceiver only triggered when using an app that requires GPS

Viewed 111

I'm developing an Android app in Java that allows a user to log and view any reviewed photography locations near them.

When the Map Fragment is opened, all locations are loaded in from a Firestore database. Once loaded, geofences are created for all locations. I have an onSuccessListener for this which logs whenever a geofence is added, so I know that this is working.

What I am trying to do is get my app to send the user a notification, and display a toast, when they have entered a geofence, regardless of if the app is open or closed. However, I am only receiving these notifications when either my app is open, or another app that is actively using the GPS is open, i.e., Google Maps.

I understand that there is a bug in the emulator which means for testing this in an emulator, you must have Google Maps open. As expected, this works. However, I am also experiencing the same issue on a real device running Android 10 (SDK 29).

My custom Broadcast Receiver is below:

public class GeofenceBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "GeofenceBroadcastReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {

        NotificationUtils notificationUtils = new NotificationUtils(context);
        GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);

        if(geofencingEvent.hasError()) {
            Log.e(TAG, "onReceive: Error receiving geofence event...");
            return;
        }

        List<Geofence> geofenceList = geofencingEvent.getTriggeringGeofences();
        for(Geofence geofence : geofenceList) {
            Log.d(TAG, "onReceive: " + geofence.getRequestId());
        }

        Location location = geofencingEvent.getTriggeringLocation();
        int transitionType = geofencingEvent.getGeofenceTransition();
        
        if(transitionType == Geofence.GEOFENCE_TRANSITION_ENTER) {
            Toast.makeText(context, "Geofence Entered...", Toast.LENGTH_SHORT).show();
            notificationUtils.sendHighPriorityNotification("Location Entered!", "location has been entered", MainActivity.class);
        } else if (transitionType == Geofence.GEOFENCE_TRANSITION_DWELL) {
            Toast.makeText(context, "Geofence Dwelled...", Toast.LENGTH_SHORT).show();
            notificationUtils.sendHighPriorityNotification("Location Dwelled!", "location has been dwelled", MainActivity.class);
        }
    }
}

My GeofenceUtils class is:

public class GeofenceUtils extends ContextWrapper {

    private static final String TAG = "GeofenceUtils";
    PendingIntent pendingIntent;

    public GeofenceUtils(Context base) {
        super(base);
    }


    public GeofencingRequest getGeofencingRequest(Geofence geofence) {
        return new GeofencingRequest.Builder()
                .addGeofence(geofence)
                .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
                .build();
    }


    public Geofence getGeofence(String id, LatLng latLng, float radius, int transitionTypes){
        return new Geofence.Builder()
                .setCircularRegion(latLng.latitude, latLng.longitude, radius)
                .setRequestId(id)
                .setTransitionTypes(transitionTypes)
                .setLoiteringDelay(0)
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                .build();
    }


    public PendingIntent getPendingIntent() {
        if(this.pendingIntent != null) {
            return this.pendingIntent;
        }
        Intent intent = new Intent(this, GeofenceBroadcastReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(this, 1010, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        return pendingIntent;
    }


    public String getErrorString(Exception e)
    {
        if (e instanceof ApiException) {
            ApiException apiException = (ApiException) e;
            switch (apiException.getStatusCode()){
                case GeofenceStatusCodes
                        .GEOFENCE_NOT_AVAILABLE:
                    return "GEOFENCE_NOT_AVAILABLE";
                case GeofenceStatusCodes
                        .GEOFENCE_TOO_MANY_GEOFENCES:
                    return "GEOFENCE_TOO_MANY_GEOFENCES";
                case GeofenceStatusCodes
                        .GEOFENCE_TOO_MANY_PENDING_INTENTS:
                    return "GEOFENCE_TOO_MANY_PENDING_INTENTS";
            }
        }
        return e.getLocalizedMessage();
    }
}

From reading similar problems, I have made sure to have PendingIntent.getBroadcast instead of PendingIntent.getService, but I still haven't had any luck.

Any help would be much appreciated!

0 Answers
Related