如果设备已经在Geofence android内部,则停止初始触发
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果设备已经在Geofence android内部,则停止初始触发相关的知识,希望对你有一定的参考价值。
我在android上使用Geofencing,当创建geo-fence时,如果用户已经在geo-fence中,设备会收到通知,这不是我正在寻找的行为,我只想通知转换ENTER和出口。
这就是我创建地理围栏请求的方式:
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的形式返回,即使我没有进入,我已经在地理围栏中了。任何人都知道如何阻止这个初始触发器?
Why you got the initial trigger
TL;博士 这是默认行为
我带着你的类似问题来到这里:
过渡类型以Geofence.GEOFENCE_TRANSITION_ENTER的形式返回,即使我没有进入,我已经在地理围栏中了。
经过一些研究,我发现这个行为在GeofencingRequest.Builder
documentation上说明:
Public Methods
public GeofencingRequest.Builder setInitialTrigger (int initialTrigger)
设置添加地理围栏时的地理围栏通知行为。默认行为是INITIAL_TRIGGER_ENTER
和INITIAL_TRIGGER_DWELL
。
要了解这些常量实际意味着什么,我们需要检查documentation for the enclosing class, GeofencingRequest
:
Constant Summary
int INITIAL_TRIGGER_DWELL
一个标志,指示地理围栏服务应在添加地理围栏时触发GEOFENCE_TRANSITION_DWELL
通知,以及设备是否已在该地理围栏中已有一段时间。
int INITIAL_TRIGGER_ENTER
一个标志,指示地理围栏服务应在添加地理围栏并且设备已在该地理围栏内时触发GEOFENCE_TRANSITION_ENTER
通知。
int INITIAL_TRIGGER_EXIT
一个标志,指示地理围栏服务应在添加地理围栏时触发GEOFENCE_TRANSITION_EXIT
通知,以及设备是否已在该地理围栏之外。
这就解释了为什么即使您没有使用GEOFENCE_TRANSITION_ENTER
也会通知你setInitialTrigger()
- 这是默认行为。
在研究这个问题时,我发现了一些有趣的东西。如果您订阅了地理围栏的入口和出口,然后将初始触发器设置为INITIAL_TRIGGER_ENTER | INITIAL_TRIGGER_EXIT
(按位OR;将两个常量相加在一起也可以),您将收到有关当前所有地理围栏(使用GEOFENCE_TRANSITION_ENTER
)以及您目前在外的所有地理围栏(使用GEOFENCE_TRANSITION_EXIT
)。我没有考虑过一个很好的用例,但无论如何它发现它很有趣。
How to stop the initial trigger
TL;博士 将初始触发器设置为0,使用常量将属性赋值给数字(例如,
private static final int NO_INITIAL_TRIGGER = 0
)
仔细看看setInitialTrigger()
的文档(请参阅本文中的第一个链接,我没有再次发布的声誉),可以阅读:
Parameters
initialTrigger
通知行为。它有点像INITIAL_TRIGGER_ENTER
和/或INITIAL_TRIGGER_EXIT
和/或INITIAL_TRIGGER_DWELL
。
使用按位运算的提示,结合为这些常量找到的文档(作为每种转换类型的标志)使我质疑如果所有位都被关闭会发生什么。
所以我试图将0
的值传递给setInitialTrigger()
,以便覆盖默认行为并关闭所有初始触发器,而不必诉诸sybilcut建议的解决方法:
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();
}
经过几个小时的测试后,这似乎是一种明智的方法,即使它依赖于记录不良的行为。
请注意:根据我执行的测试,根据所选地理围栏的半径和当前位置的精度,仍然可以获得几乎即时的过渡触发器。
例如,您可能稍微远离地理围栏,然后突然更新您的位置,将您置于地理围栏内:这将触发地理围栏入口通知。但是,此入口通知与您配置的初始触发器无关,而与您感知位置的更新无关。
在离开的注释中,如果你不介意,我建议另一种方法来实现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...
}
解决方法可能是将INITIAL_TRIGGER_DWELL
传递给setInitialTrigger()
方法。如果设备已经在地理围栏内一段时间,这将仅触发通知。您可以将此时间设置为非常大的数字。但是,只有在初始触发时单独使用GEOFENCE_TRANSITION_DWELL
并且对添加暂停通知不感兴趣时,这才有效。
以上是关于如果设备已经在Geofence android内部,则停止初始触发的主要内容,如果未能解决你的问题,请参考以下文章
当手机靠近受监控的位置时,Android ProximityAlert 或 Geofence 是不是会消耗更多电量?
Android 地理围栏在进入/退出时触发,没有错误但没有 GEOFENCE_TRANSITION_ 标志