使用 GeofencingClient 时地理围栏不适用于退出转换

Geofencing not working for Exit Transition when using GeofencingClient

我正在尝试设置地理围栏,以便在用户退出 100m 地理围栏时在我的 BroadcastReceiver 上获得回调 Location。这是我实现的。

public class GeofenceTask implements OnCompleteListener<Void> {
public static final String LAST_STILL_LOCATION_GEO_FENCE_ID = "LastStillLocationGeoFence";
private Context context;

public GeofenceTask(Context context) {
    this.context = context;
}

@SuppressLint("MissingPermission")
public void setupGeoFence(double latitude, double longitude) {
    Timber.e("Setting up Geofence on Lat: " + latitude + ", Lon :" + longitude);
    GeofencingClient client = LocationServices.getGeofencingClient(context);
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_EXIT);

    // Add the geofences to be monitored by geofencing service.
    builder.addGeofence(createGeoFencingRequest(latitude, longitude));

    // Return a GeofencingRequest.
    GeofencingRequest geofencingRequest = builder.build();
    client.addGeofences(geofencingRequest, getGeofencePendingIntent()).addOnCompleteListener(this);

}

public void setupGeoFence(Location location) {
    setupGeoFence(location.getLatitude(), location.getLongitude());
}

public void removeAnyGeoFences() {
    GeofencingClient client = LocationServices.getGeofencingClient(context);
    client.removeGeofences(getGeofencePendingIntent()).addOnCompleteListener(this);

}

private PendingIntent getGeofencePendingIntent() {
    Intent intent = new Intent(context, GeofenceTransitionReceiver.class);
    intent.setAction(GeofenceTransitionReceiver.ACTION_GEOFENCE_TRANSITION);
    return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

private Geofence createGeoFencingRequest(double latitude, double longitude) {
    return new Geofence.Builder()
            .setRequestId(LAST_STILL_LOCATION_GEO_FENCE_ID)
            .setCircularRegion(latitude, longitude,100)
            .setExpirationDuration(Geofence.NEVER_EXPIRE)
            .setNotificationResponsiveness(0)
            .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
            .build();
}
@Override
public void onComplete(@NonNull Task<Void> task) {
    if (task.isSuccessful()) {
        Timber.i("Geofence Task onComplete");
    } else {
        // Get the status code for the error and log it using a user-friendly message.
        String errorMessage = GeofenceErrorMessages.getErrorString(context, task.getException());
        Timber.e(errorMessage);
    }
}

BroadcastReceiver 代码

public class GeofenceTransitionReceiver extends BroadcastReceiver {

static final String ACTION_GEOFENCE_TRANSITION = PACKAGE_NAME + ".ACTION_GEOFENCE_TRANSITION";


@Override
public void onReceive(Context context, Intent intent) {
    Timber.i("onReceive");
    if (intent != null) {
        final String action = intent.getAction();
        if (ACTION_GEOFENCE_TRANSITION.equals(action)) {
            GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
            if (geofencingEvent.hasError()) {
                String errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.getErrorCode());
                Timber.e(errorMessage);
                return;
            }

            // Get the transition type.
            int geofenceTransition = geofencingEvent.getGeofenceTransition();

            // Test that the reported transition was of interest.
            if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {

                Location newLocation = geofencingEvent.getTriggeringLocation();
                Timber.i("Triggering Location " + newLocation.toString() + "!!!!!!");

                // Get the geofences that were triggered. A single event can trigger multiple geofences.
                List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
                Timber.i("--------Triggering GeoFences Start------");
                for (Geofence geofence : triggeringGeofences) {
                    Timber.i(geofence.toString());
                }
                Timber.i("--------Triggering GeoFences End ------");
            } else {
                // Log the error.
                Timber.e(context.getString(R.string.geofence_transition_invalid_type, geofenceTransition));
            }
        } else {
            Timber.w("Invalid Action");
        }
    } else {
        Timber.w("Intent Null");
    }
}

我在模拟器中测试时已授予该应用程序位置权限。这就是我声明我的 BroadcastReceiver.

的方式
 <receiver
        android:name=".location.geofence.GeofenceTransitionReceiver"
        android:exported="true">
    </receiver>

然后我打电话给:

 GeofenceTask geofenceTask = new GeofenceTask(this);
 geofenceTask.setupGeoFence(37.7042, -122.471);

现在在模拟器中,当我将位置发送为纬度 - 37.7051 和经度 - -122.47 时。我在 GeofenceTransitionReceiver.

没有接到电话

原来我的代码是有效的。只是在模拟器中地理围栏不起作用,因为地理围栏使用 network/wifi 信息来触发 Geofence 转换。当我在物理设备上测试时,我的代码有效。