【问题标题】:How to increase consistency of Android geofence enter/exit notifications?如何提高 Android 地理围栏进入/退出通知的一致性?
【发布时间】:2014-02-20 06:10:24
【问题描述】:

我正在使用内置的地理围栏 API(播放服务)并且结果好坏参半。看起来在设置地理围栏后,即使 GPS 开启,进入/退出的通知也非常不一致,具有最新的位置(LocationClient 已连接,在后台运行。)我开始监控(轮询)位置变化和调试文本字段中的距离,并看到,即使基于设备注册的位置和地理围栏的位置,我在技术上位于地理围栏内部/外部,有时会触发通知,有时不会触发通知。有什么办法可以让这更可预测?我几乎想放弃这个 api 并根据设备位置的轮询实现我自己的(电池耗尽)地理围栏。

【问题讨论】:

    标签: android android-maps-v2 android-geofence


    【解决方案1】:

    几个建议:

    1. 确保您使用的是 BroadcastReceiver 而不是 Service 来接收转换,否则如果您的应用程序被杀死/关闭,您将不会/可能不会收到它。正如这里所讨论的: Android Geofence eventually stop getting transition intents

    2. 确保在设备重新启动后重新创建地理围栏,最好使用引导广播接收器。正如这里所讨论的: Do Geofences remain active in android after a device reboot

    3. 另一个常见的误解让我感到困惑,因为它与 IOS 不同,如果设备在创建地理围栏时发现您在地理围栏内,您总是会立即获得新创建的地理围栏的触发器.我已经使用新创建的地理围栏的“宽限期”自己解决了这个问题,我在这个线程中解释了这一点: addProximityAlert doesn't work as expected

    最后一件重要的事情:是否将 LocationClient 连接到您的应用中如果您遵循上述几点,则根本不重要。我在代码中添加或删除地理围栏的过程基本上是:

    1. 创建并连接 locationclient。

    2. 在连接回调中,添加/删除地理围栏

    3. 在 geofence-result 回调中,断开 locationclient。

    每次发生这种情况时,我的定位客户端总共只连接了几秒钟。操作系统仍会生成地理围栏警报并在它们发生时调用我的 BroadcastReceiver。

    如果您做这些事情,我敢打赌您的体验会有所改善。

    希望这会有所帮助!

    【讨论】:

    • 我会尝试#1。 #2 和 #3 不适用于我的项目,尽管它是总体有用的信息。另外,很高兴知道 LocationClient 与此无关,因为我付出了一些努力来保持它的热度并定期运行位置更新。消除这些肯定会使应用程序更轻巧,电池/资源效率更高。
    • 好东西,很高兴能帮上忙!
    • 不幸的是,在进行了建议的更新后,没有任何改进。此外,如果您遵循上述几点,“是否在您的应用程序中连接您的 LocationClient 并不重要”。似乎并不准确,因为在某些情况下,当客户端断开连接时我没有收到任何通知,但是一旦我连接,它们就会开始进入。所有这一切都非常令人沮丧,因为我的项目的重要功能取决于应该工作的东西纸上谈兵,但实际上失败得很惨。
    • 抱歉,您仍有问题。不过,我很确定,您不需要连接 LocationClient 来获取回调。 locationclient 是执行位置相关操作的“通道”。我把它看成是打电话。我的广播意图在我们的应用程序被销毁后得到回调,并且在手机重启后无需实际启动我们的应用程序,所以我很确定它可以工作。如果您查看 LocationClient 的 APIDocs,这基本上也是它所说的内容。希望你解决伙计!
    • Leon,是的,我已经在答案中写了。 “如果设备在创建时发现您在地理围栏内”
    【解决方案2】:

    我尝试了接受回复中的所有建议,但准确度对我来说并不好。如果您在这里寻找更多想法,您应该阅读以下内容。

    我能够根据android location api 加上JTS Location Suite 自己的地理围栏算法来解决问题

    为了更准确。您只需创建一个 jts 多边形,在数学上代表您的围栏。

    static GeometryFactory GF = new GeometryFactory();
    
    public Polygon getPolygon() {
        ArrayList<Coordinate> coors = new ArrayList<>();
        
        for (Point p : getPolygonPoints()) {
            coors.add(new Coordinate(p.lat, p.lon));
        }
    
        // close the polygon is needs
        final Coordinate first = coors.get(0);
        final Coordinate last = coors.get(coors.size()-1);
        if (!first.equals2D(last)) {
            coors.add(coors.get(0));
        }
    
        // create polygon
        return GF.createPolygon(coors.toArray(new Coordinate[] {}));
    }
    

    然后您可以检查当前 GPS 点是否在给定多边形内。

    final Point point = GF.createPoint(new Coordinate(lat, lon));
    if (point.within(getPolygon())) {
       // hit
    } else {
       // miss
    }
    

    就是这样。然后您可以创建一个java.util.Timer 来定期迭代多边形列表(地理围栏)以了解哪个被击中或哪个在后面。

    注意:在您的模块 build.gradle 中添加以下内容以在您的项目中添加 JTS 库:

    implementation(group: 'org.locationtech.jts.io', name: 'jts-io-common', version: '1.18.1') {
       exclude(group: 'org.hamcrest')
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      相关资源
      最近更新 更多