我在 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 即使我没有进入,我已经在地理围栏内。 任何人都知道如何停止这个初始触发器?
最佳答案
为什么你得到了初始触发
tl;dr
It's the default behavior
我遇到了你的类似问题:
The transition type is returned as Geofence.GEOFENCE_TRANSITION_ENTER even though I am not entering, I am already inside the geofence.
经过一番研究后,我发现 GeofencingRequest.Builder
documentation 上声明了这种行为:
Public Methods
public GeofencingRequest.Builder setInitialTrigger (int initialTrigger)
Sets the geofence notification behavior at the moment when the geofences are added. The default behavior isINITIAL_TRIGGER_ENTER
andINITIAL_TRIGGER_DWELL
.
要了解这些常量的实际含义,我们需要检查 documentation for the enclosing class, GeofencingRequest
:
Constant Summary
int INITIAL_TRIGGER_DWELL
A flag indicating that geofencing service should triggerGEOFENCE_TRANSITION_DWELL
notification at the moment when the geofence is added and if the device is already inside that geofence for some time.
int INITIAL_TRIGGER_ENTER
A flag indicating that geofencing service should triggerGEOFENCE_TRANSITION_ENTER
notification at the moment when the geofence is added and if the device is already inside that geofence.
int INITIAL_TRIGGER_EXIT
A flag indicating that geofencing service should triggerGEOFENCE_TRANSITION_EXIT
notification at the moment when the geofence is added and if the device is already outside that geofence.
这解释了为什么即使您没有使用 setInitialTrigger()
也会收到 GEOFENCE_TRANSITION_ENTER
通知 - 这是默认行为。
在调查这个问题的过程中,我发现了一些有趣的事情。如果您订阅了地理围栏的入口和导出,然后将初始触发器设置为 INITIAL_TRIGGER_ENTER | INITIAL_TRIGGER_EXIT
(按位或;将两个常量相加也可以),您将收到有关您当前所在的所有地理围栏(使用 GEOFENCE_TRANSITION_ENTER
)以及您所在的所有地理围栏的通知目前在外面(GEOFENCE_TRANSITION_EXIT
)。我还没有想出一个好的用例,但无论如何都觉得它很有趣。
如何停止初始触发器
tl;dr
Set the initial trigger to 0, using a constant to attribute meaning to the number (e.g.,private static final int NO_INITIAL_TRIGGER = 0
)
仔细研究 documentation of setInitialTrigger()
可以阅读:
Parameters
initialTrigger
the notification behavior. It's a bit-wise ofINITIAL_TRIGGER_ENTER
and/orINITIAL_TRIGGER_EXIT
and/orINITIAL_TRIGGER_DWELL
.
使用按位运算的提示,结合为这些常量找到的文档(它们用作每种类型转换的标志)让我质疑如果所有位都关闭会发生什么。
所以我尝试将 0
的值传递给 setInitialTrigger()
,以便覆盖默认行为并关闭所有初始触发器而无需求助到 workaround proposed by rfn123 :
private GeofencingRequest createGeofencingRequest(List<Geofence> geofences) {
return new GeofencingRequest.Builder()
.setInitialTrigger(0)
.addGeofences(geofences)
.build();
}
或者 - 甚至更好 - 赋予魔数(Magic Number)一些意义:
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...
}
关于android - 如果设备已经在 Geofence android 中,则停止初始触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44179175/