Android 地理围栏转换触发器

Android geofence transition triggers

我正在构建一个包含 googles 地理围栏的应用程序,这是我使用 ENTEREXIT 转换创建的. 打开“Location”时会出现问题,当在我的地理围栏内时,它会触发两个转换,而只有 ENTER 转换应该触发。 我已将 ENTEREXIT 都设置为 intitialTrigger().

这怎么可能?

是 google api 的错误还是我在生成器中做错了什么。提前致谢。

@Override
public void onResult(Result result) {
    Status s = result.getStatus();
    Log.d(TAG, "onResult(...)" + s.isSuccess());
    if (!s.isSuccess()) {
        Log.d(TAG, "statuskode = " + s.getStatusCode() +
                "  noget gik galt, sandsynlighvis blev gps slået fra = statuscode 1000");
    }
}

private GeofencingRequest createGeoFences() {
    return new GeofencingRequest.Builder()
            .addGeofence(geoFenceBuilder(Constants.LOCATION_BALLERUP, "ballerup_req_id"))
            .addGeofence(geoFenceBuilder(Constants.LOCATION_AALBORG, "aalborg_req_id"))
            .addGeofence(geoFenceBuilder(Constants.LOCATION_ESBJERG, "esbjerg_req_id"))
            .addGeofence(geoFenceBuilder(Constants.LOCATION_ÅRHUS, "århus_req_id"))
                    //  .addGeofence(geoFenceBuilder(Constants.LOCATION_TAASTRUP, 44))
            .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_EXIT)
            .build();
}

private Geofence geoFenceBuilder(LatLng location, String requestId) {

    return new Geofence.Builder().setCircularRegion(location.latitude, location.longitude, TARGET_RADIUS)
            .setExpirationDuration(Geofence.NEVER_EXPIRE)
            .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
            .setRequestId(requestId)
            .setNotificationResponsiveness(NOTIFICATION_DELAY)
            .build();
}

您需要注册一个可以处理触发器的 IntentService

public class GeofenceTransitionsIntentService extends IntentService {
   ...
protected void onHandleIntent(Intent intent) {

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

    // Test that the reported transition was of interest.
    if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ) {
        //TODO: on Transition Enter
    }else if(geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT){
        //TODO: on Transition Exit
    }else{
      Log.e(GEOFENCE, "Event not handled",
                geofenceTransition));
    }

此处解释:http://developer.android.com/training/location/geofencing.html

如果您需要知道您是否在地理围栏内,您可以循环查看当前的地理围栏位置列表并检查其中一个位置是否足够接近触发?

像这样:

public Location insideGeofenceLocation(Location currentLocation, ArrayList<Location> listOfGeofenceLocations, float triggerRadius) {
    for (Location geoFenceLocation : listOfGeofenceLocations) {
        if (currentLocation.distanceTo(geoFenceLocation) < triggerRadius)
            return geoFenceLocation;
    }
    return null;
}

检查当前位置:

Location geofenceLocation = insideGeofenceLocation(locationClient.getLastLocation(), listOfGeofenceLocations, TARGET_RADIUS);
if(geofenceLocation!=null){
    // TODO: update
}

这可能是 Google 的地理围栏 API 部分的一些奇怪错误。此外,将 ENTER 和 EXIT 事件都作为初始触发器有点奇怪。这是动态调用 setInitialTrigger() 并完全避免这种情况的简单解决方案。在调用 createGeoFences() 之前,获取一个 GPS 点并检查从该点到地理围栏中心点的距离。如果在地理围栏外,只需传一个值设置初始触发为GEOFENCE_TRANSITION_ENTER,否则,设置为GEOFENCE_TRANSITION_EXIT.

至于为什么会这样,这是我的想法,虽然我还没有测试过。 Google 可能正在获取最后一个已知位置,该位置最初可能在地理围栏之外,因此注册了 GEOFENCE_TRANSITION_EXIT 事件。然后它会启动它的位置堆栈,看到 phone 实际上在地理围栏内,然后注册 GEOFENCE_TRANSITION_ENTER 事件。