【问题标题】:Stop initial triggering if device is already inside Geofence android如果设备已经在 Geofence android 中,则停止初始触发
【发布时间】:2017-05-25 11:14:18
【问题描述】:

我在 android 上使用地理围栏,在创建地理围栏时,如果用户已经在地理围栏内,设备会收到通知,这不是我要寻找的行为,我只想通知转换 ENTER 和 EXIT。

这就是我创建地理围栏请求的方式:

private GeofencingRequest createGeoFenceRequest(List<Geofence> geofenceList) {
        return new GeofencingRequest.Builder()

                //The INITIAL_TRIGGER_ENTER is used to notify the user initially if he/she/other
                //is already inside the geo-fence zone
                //.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)

                .addGeofences(geofenceList)
                .build();
    }

在我的 GeofenceTransitionService.java 中:

@Override
protected void onHandleIntent(@Nullable Intent intent) {

    if (intent != null) {
        geofencingEvent = GeofencingEvent.fromIntent(intent);

        // Retrieve the transition type.
        geoFenceTransition = geofencingEvent.getGeofenceTransition();

    }
}

转换类型返回为 Geofence.GEOFENCE_TRANSITION_ENTER 即使我没有进入,我已经在地理围栏内。 任何人都知道我可以如何停止这个初始触发器?

【问题讨论】:

    标签: android geolocation location geofencing android-geofence


    【解决方案1】:

    为什么你得到了初始触发器

    tl;dr
    这是默认行为

    我遇到了你的类似问题:

    转换类型返回为 Geofence.GEOFENCE_TRANSITION_ENTER 即使我没有进入,我已经在地理围栏内。

    经过一番研究,我发现GeofencingRequest.Builder documentation 上说明了这种行为:

    公共方法

    public GeofencingRequest.Builder setInitialTrigger (int initialTrigger)
    设置添加地理围栏时的地理围栏通知行为。默认行为是INITIAL_TRIGGER_ENTERINITIAL_TRIGGER_DWELL

    要了解这些常量的实际含义,我们需要检查documentation for the enclosing class, GeofencingRequest

    不断总结

    int INITIAL_TRIGGER_DWELL
    一个标志,指示地理围栏服务应在添加地理围栏时触发GEOFENCE_TRANSITION_DWELL 通知,并且如果设备已经在该地理围栏内一段时间。

    int INITIAL_TRIGGER_ENTER
    指示地理围栏服务应在添加地理围栏时以及设备已在该地理围栏内时触发GEOFENCE_TRANSITION_ENTER 通知的标志。

    int INITIAL_TRIGGER_EXIT
    一个标志,指示地理围栏服务应在添加地理围栏时触发GEOFENCE_TRANSITION_EXIT 通知,如果设备已经在该地理围栏之外。

    这解释了为什么即使您没有使用 setInitialTrigger() 也会通知您 GEOFENCE_TRANSITION_ENTER - 这是默认行为。

    在调查这件事时,我发现了一些有趣的事情。如果您订阅地理围栏的入口和离开,然后将初始触发器设置为INITIAL_TRIGGER_ENTER | INITIAL_TRIGGER_EXIT(按位或;将两个常数相加也可以),您将收到当前所在的所有地理围栏的通知(GEOFENCE_TRANSITION_ENTER ) 以及您目前在外面的所有地理围栏(使用GEOFENCE_TRANSITION_EXIT)。我还没有想到一个好的用例,但无论如何发现它很有趣。


    如何停止初始触发

    tl;dr
    将初始触发器设置为 0,使用常量将含义赋予数字(例如,private static final int NO_INITIAL_TRIGGER = 0

    仔细查看documentation of setInitialTrigger(),可以阅读:

    参数

    initialTrigger 通知行为。这有点像INITIAL_TRIGGER_ENTER 和/或INITIAL_TRIGGER_EXIT 和/或INITIAL_TRIGGER_DWELL

    使用按位运算的提示,结合为这些常量找到的文档(它们作为每种转换类型的标志)让我质疑如果所有位都关闭会发生什么。

    所以我尝试将0 的值传递给setInitialTrigger(),以覆盖默认行为并关闭所有初始触发器,而不必求助于workaround proposed by rfn123

    private GeofencingRequest createGeofencingRequest(List<Geofence> geofences) {
        return new GeofencingRequest.Builder()
                .setInitialTrigger(0)
                .addGeofences(geofences)
                .build();
    }
    

    或者——也许更好——赋予幻数一些意义:

    private static final int NO_INITIAL_TRIGGER = 0;
    
    private GeofencingRequest createGeofencingRequest(List<Geofence> geofences) {
        return new GeofencingRequest.Builder()
                .setInitialTrigger(NO_INITIAL_TRIGGER)
                .addGeofences(geofences)
                .build();
    }
    

    经过几个小时的测试,这似乎是一种明智的方法即使它依赖于记录不充分的行为(如keepTrackOfYourStack has noticed,文档已更新以澄清这一点)。


    请注意:根据我执行的测试,根据所选地理围栏的半径和当前位置的精度,仍然可以几乎立即触发过渡。

    例如,您可能稍微远离地理围栏,然后突然更新您的位置,将您置于地理围栏内:这将触发地理围栏进入通知。 但是,这个进入通知与您配置的初始触发器无关,而是与您感知位置的更新有关。


    顺便说一句,如果您不介意,我有一个替代方法来实现onHandleIntent() 方法的建议。

    无需检查intent 对象的无效性,只需将该责任传递给GeofencingEvent#fromIntent() 调用即可。 然后,您可以使用保护子句检查返回的event 对象的有效性——这将增加您的方法的可读性(至少在我看来)。 这将允许您测试无效性并检查事件是否有错误。

    类似这样的:

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        GeofencingEvent event = GeofencingEvent.fromIntent(intent);
        if (event == null || event.hasError()) {
            logInvalidEvent(event);
            return;
        }
    
        // Process the event...
    }
    

    【讨论】:

      【解决方案2】:

      解决方法可能是将INITIAL_TRIGGER_DWELL 传递给setInitialTrigger() 方法。 如果设备已经在地理围栏内一段时间,这只会触发通知。您可以将此时间设置为一个非常大的数字。 但是,这仅适用于您在初始触发中仅使用 GEOFENCE_TRANSITION_DWELL 并且对添加暂停通知不感兴趣的情况。

      查看此链接:https://developers.google.com/android/reference/com/google/android/gms/location/GeofencingRequest#INITIAL_TRIGGER_ENTER

      【讨论】:

        【解决方案3】:

        看起来他们修复了文档,即使没有常量也可以 0 工作

        documentation update

        【讨论】:

          【解决方案4】:

          来自文档

          initialTrigger 通知行为。 它是 GeofencingRequest.INITIAL_TRIGGER_ENTER 和/或 GeofencingRequest.INITIAL_TRIGGER_EXIT 和/或 GeofencingRequest.INITIAL_TRIGGER_DWELL 的位。 当 initialTrigger 设置为 0 (setInitialTrigger(0)) 时,初始触发器将被禁用。

          【讨论】:

            猜你喜欢
            • 2022-09-25
            • 2014-10-07
            • 1970-01-01
            • 1970-01-01
            • 2019-09-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多