Geofencing больше не работает с JobIntentService - PullRequest
0 голосов
/ 28 мая 2018

У меня есть IntentService для геозон, который я бы просто начал.но он должен работать в фоновом режиме, поэтому в Android 8 он иногда попадает в белый список.Поэтому мне трудно использовать JobIntentService: https://developer.android.com/reference/android/support/v4/app/JobIntentService Также посмотрел на это: Android 8.0: java.lang.IllegalStateException: не разрешено запускать службу Intent

Это былоmy onHandleIntent (), где я получаю свои вызовы Geofence:

  //HANDLING INTENTS
protected void onHandleIntent(Intent intent) {
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
    if (geofencingEvent != null) {
        int transitionType = geofencingEvent.getGeofenceTransition();
        if (transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
            Location triggering = geofencingEvent.getTriggeringLocation();
            if (triggering != null) {
                Utils.appendLog("GEOFENCE onHandleIntent got an EXIT transition: " + triggering.getLatitude() + ", " + triggering.getLongitude() + " / accuracy: " + triggering.getAccuracy(), "D", "#updategeo " + Constants.GEOFENCE);
            } else
                Utils.appendLog("GEOFENCE onHandleIntent got an EXIT transition null", "D", "#updategeo " + Constants.GEOFENCE);
            Utils.appendLog("removing geofence after exit", "I", Constants.TRACKER + "#updategeo");
            removeGeofencesAndStartTracking();
        }
    }
}

Это был мой код для моей службы Intent, добавьте логику геозоны:

  //ADDING/REMOVING GEOFENCES
public void addGeofence(final Context context, final Location location, float radius) {
    if (!isSettingGeofence) {
        isSettingGeofence = true;
        ArrayList geofences = new ArrayList<>();
        geofences.add(new Geofence.Builder()
                .setRequestId(geofenceRequestID)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
                .setCircularRegion(
                        location.getLatitude(), location.getLongitude(), radius)
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                .build());

        if (geofences.size() > 0) {
            if (mGeofencingClient == null)
                mGeofencingClient = LocationServices.getGeofencingClient(this);

            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                Utils.appendLog("Geofence Transitions Service addGeofence checkSelfPermission ERROR", "E", Constants.GEOFENCE);
                return;
            }

            Utils.appendLog("addGeofences is being called, wait for success or failure callbacks", "I", Constants.TRACKER + "#updategeo");
            mGeofencingClient.addGeofences(getGeofencingRequest(location, geofences), getGeofencePendingIntent(context)).addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    PSLocationService.getInstance(context).lastTimeDidExitRegion = null;
                    isSettingGeofence = false;
                    final RealmLocation realmLocation = new RealmLocation(location.getLatitude(), location.getLongitude(), location.getTime(), null, true);
                    Log.i("#geofenceRequestID", "addGeofence geofence realm location: " + realmLocation.getLocation());
                    final GeofenceRealmLocation geofenceRealmLocation = new GeofenceRealmLocation(geofenceRequestID, realmLocation);
                    Log.i("#geofenceRequestID", "addGeofence geofence geofence location: " + geofenceRealmLocation.getRealmLocation().getLocation());
                    realmLocation.setAccuracy(location.getAccuracy());
                    realmLocation.setSpeed(location.getSpeed());
                    Log.i("", "GLOBAL intances  before addGeofences:" + Realm.getGlobalInstanceCount(PSApplicationClass.Config));
                    Realm realm = Realm.getInstance(PSApplicationClass.Config);
                    realm.executeTransaction(new Realm.Transaction() {
                        @Override
                        public void execute(Realm realm) {
                            realm.copyToRealmOrUpdate(geofenceRealmLocation);
                        }
                    });
                    realm.close();
                    try {
                        final NotificationManager notifManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                        notifManager.cancel(1010);
                    } catch (Exception e) {
                        Utils.appendLog("Error removing notification: " + e.getMessage(), "I", Constants.GEOFENCE);
                    }

                    Log.i("", "GEOFENCETEST addGeofences SUCCESSS");
                    Utils.appendLog("Geofence Transitions Service setGeofenceRequest Success adding geofences!" +
                                    location.getLatitude() +
                                    " , " + location.getLongitude() + " / accuracy: " + location.getAccuracy(),
                            "I",
                            "#updategeo " + Constants.GEOFENCE);
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.i("", "GEOFENCETEST addGeofences FAILURE: " + e.getMessage());
                    isSettingGeofence = false;
                    try {
                        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
                        boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                        if (!networkEnabled) {
                            new Handler(Looper.getMainLooper()).post(new Runnable() {
                                @Override
                                public void run() {
                                    MyFirebaseMessagingService.generateNotificationStandard(context, null, context.getString(R.string.Error) + ": " + context.getString(R.string.geofence_error), null, null, false, false, MyFirebaseMessagingService.NETWORK_ERROR_NOTIFICATION);
                                }
                            });
                        }
                    } catch (Exception ex) {
                        Log.e("", "");
                        // catch Exception
                    }
                    Utils.appendLog("Geofence Transitions Service setGeofenceRequest FAILURE adding geofences!" +
                                    e.getMessage(),
                            "E",
                            "#updategeo " + Constants.GEOFENCE);
                }
            });
        } else {
            Utils.appendLog("Geofence Transitions Service geofences size Error: " + geofences.size(), "E", Constants.GEOFENCE);
        }
    } else
        Utils.appendLog("Geofence Transitions Service setGeofenceRequest is already setting a geofence", "I", Constants.GEOFENCE);
}

Теперь я изменил на JobIntentService.

Я запускаю службу следующим образом:

   Intent bindIntent = new Intent(context, PSGeofenceTransitionsIntentService.class);
        enqueueWork(context, bindIntent);

  public static final int JOB_ID = 1;

public static void enqueueWork(Context context, Intent work) {
    enqueueWork(context, PSGeofenceTransitionsIntentService.class, JOB_ID, work);
}

Я также добавил это в свой манифест Android:

  <service android:name=".core.tracking.PSGeofenceTransitionsIntentService"
        android:permission="android.permission.BIND_JOB_SERVICE"/>

И я обращаюсь с содержанием onHandleIntent в NEWonHandleWork

  @Override
protected void onHandleWork(@NonNull Intent intent) {
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
    if (geofencingEvent != null) {
        int transitionType = geofencingEvent.getGeofenceTransition();
        if (transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
            Location triggering = geofencingEvent.getTriggeringLocation();
            if (triggering != null) {
                Utils.appendLog("GEOFENCE onHandleIntent got an EXIT transition: " + triggering.getLatitude() + ", " + triggering.getLongitude() + " / accuracy: " + triggering.getAccuracy(), "D", "#updategeo " + Constants.GEOFENCE);
            } else
                Utils.appendLog("GEOFENCE onHandleIntent got an EXIT transition null", "D", "#updategeo " + Constants.GEOFENCE);
            Utils.appendLog("removing geofence after exit", "I", Constants.TRACKER + "#updategeo");
            removeGeofencesAndStartTracking();
        }
    }
}

Теперь я получаю события onHandleWork из Geofence, но только с типом перехода = -1.Поэтому я не получаю события ВВОД или ВЫХОД.Почему или как я могу исправить эту службу Geofence?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Во-первых, вам нужно настроить Broadcast Receiver, где в вашем методе onReceive вы ставите Work для вашего JobIntentService.Таким образом, вместо непосредственного запуска IntentService вы вызываете широковещательный приемник в своем PendingIntent.

0 голосов
/ 31 июля 2018

Была такая же проблема.С Android 8 фоновая работа более ограничена.Существует новый способ звонить PendingIntent.Вам не нужно менять его на JobIntentService.Ознакомьтесь с новейшими рекомендациями Android по реализации прослушивателя Geofence:

https://developer.android.com/training/location/geofencing

Короче говоря, вам просто нужно использовать GeofencingClient для вызова PendingIntent.

private PendingIntent getGeofencePendingIntent() {
    // Reuse the PendingIntent if we already have it.
    if (mGeofencePendingIntent != null) {
        return mGeofencePendingIntent;
    }
    Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
    // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when
    // calling addGeofences() and removeGeofences().
    mGeofencePendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.
            FLAG_UPDATE_CURRENT);
    return mGeofencePendingIntent;
}

Используйте приведенную выше ссылку для полного примера.

...