使用GeofencingClient时,Geofencing不适用于Exit Transition

时间:2017-11-01 03:31:09

标签: android google-play-services geofencing android-geofence

我正在尝试设置Geofence,以便当用户退出100m Location周围的地理围栏时,我会在BroadcastReceiver上收到回调。这就是我实施的内容。

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

现在我在模拟器中发送位置为Latitude - 37.7051和经度 - -122.47。我没有接到GeofenceTransitionReceiver的电话。

1 个答案:

答案 0 :(得分:0)

结果证明我的代码正常运行。只是在仿真器中地理围栏不起作用,因为地理围栏使用网络/ wifi信息来触发Geofence转换。当我在物理设备上测试时,我的代码工作正常。