Android BroadcastReceiver запускается только при использовании приложения, для которого требуется GPS

#android #broadcastreceiver #android-notifications #android-location #android-geofence

Вопрос:

Я разрабатываю приложение для Android на Java, которое позволяет пользователю регистрироваться и просматривать любые просмотренные места съемки рядом с ними.

Когда фрагмент карты открыт, все местоположения загружаются из базы данных Firestore. После загрузки геозоны создаются для всех местоположений. Для этого у меня есть onSuccessListener, который регистрируется всякий раз, когда добавляется геозона, поэтому я знаю, что это работает.

То, что я пытаюсь сделать, — это заставить мое приложение отправлять пользователю уведомление и отображать тост, когда они вошли в геозону, независимо от того, открыто приложение или закрыто. Однако я получаю эти уведомления только тогда, когда открыто либо мое приложение, либо открыто другое приложение, активно использующее GPS, т. Е. Карты Google.

Я понимаю, что в эмуляторе есть ошибка, которая означает, что для тестирования этого в эмуляторе у вас должны быть открыты карты Google. Как и ожидалось, это работает. Однако я также испытываю ту же проблему на реальном устройстве под управлением Android 10 (SDK 29).

Мой пользовательский широковещательный приемник находится ниже:

 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);
        }
    }
}
 

Мой класс GeofenceUtils-это:

 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!