如果设备已经在Geofence android内部,则停止初始触发

问题描述 投票:1回答:2

我在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的形式返回,即使我没有进入,我已经在地理围栏中了。任何人都知道如何阻止这个初始触发器?

android geolocation location geofencing android-geofence
2个回答
6
投票

Why you got the initial trigger

TL;博士 这是默认行为

我带着你的类似问题来到这里:

过渡类型以Geofence.GEOFENCE_TRANSITION_ENTER的形式返回,即使我没有进入,我已经在地理围栏中了。

经过一些研究,我发现这个行为在GeofencingRequest.Builder documentation上说明:

Public Methods

public GeofencingRequest.Builder setInitialTrigger (int initialTrigger) 设置添加地理围栏时的地理围栏通知行为。默认行为是INITIAL_TRIGGER_ENTERINITIAL_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...
}

1
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.