【问题标题】:Displaying a notification only when a beacon is detected for a certain period of time仅在特定时间段内检测到信标时才显示通知
【发布时间】:2017-04-05 10:40:27
【问题描述】:

我对 Android 应用程序编程非常陌生,想询问有关信标的问题。

目前,我正在使用 AltBeacon android-beacon-library 编写应用程序。我喜欢实现一个功能:

理想情况下,我希望在用户靠近特定信标时显示通知。但是,我只想在用户在该信标周围超过 30 秒时才显示通知。如果用户只是走过信标,那么我不希望显示通知。

请问有没有现成的方法呢?我知道有一种名为“startMonitoringBeaconsInRegion”的方法,但我真的不知道这是否合适。任何帮助将不胜感激。

【问题讨论】:

    标签: java android android-notifications monitoring ibeacon


    【解决方案1】:

    使用后台服务通过计时器获取信标可用性。当您获得信标存在时启动计时器并在 30 秒后触发通知,如果信标在该位置可用 30 秒,否则重置计时器。

    Beacon 后台搜索:http://developer.estimote.com/android/tutorial/part-2-background-monitoring/

    上面的教程链接看起来很有希望

        //start when found beacon in background
    
       Timer timer = new Timer();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
    
                            getActivity().runOnUiThread(new Runnable() {
                                public void run() {
                                    try {
                                     //send notification
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            });
                        }
                    }, 30000);
    

    //如果信标状态为假或不可用则重置

       if (timer != null) {
       timer.cancel();
       }
    

    【讨论】:

    • 谢谢。你能解释一下后台服务吗?如果您不介意,可以给我一些代码吗?我对编程比较陌生,所以想要更多解释。谢谢:)
    【解决方案2】:

    您可以通过 Android 信标库使用测距轻松实现这一点。遵循有关设置测距的常规教程。然后在您的测距回调中添加如下代码:

    HashMap<String,Long> beaconDetections = new HashMap<String,Long>();
    
    public void didRangeBeaconsInRegion(Region region, Collection<Beacon> beacons) {
      Long now = System.currentTimeMillis();
      for (Beacon beacon : beacons) {
        Long firstDetectionTime = beaconDetections.get(beacon.toString());
        if (firstDetectionTime != null) {
          if (now-firstDetectionTime > 30000l) {
            // Put logic here for if beacon seen for 30 secs or more
          }
        }
        else {
          beaconDetections.put(beacon.toString(), now);   
        }
      }
    }
    

    上面的代码使用 HashMap 来跟踪第一次看到每个信标的时间,然后在每个回调上执行特殊逻辑(如果已经看到 30 秒或更长时间)。

    【讨论】:

    • 非常感谢。我对此很陌生,所以想澄清一下:当您说设置测距时,您的意思是使用 startRangingBeaconsInRegion() 方法吗?测距回调是什么意思?另外,我很难理解测距和监控之间的区别?实际区别是什么?
    • Ranging 每秒发送一个回调,其中包含在您调用 startRangingBeaconsInRegion() 后检测到的信标列表。在此处查看测距示例代码:altbeacon.github.io/android-beacon-library/samples.html
    • 感谢大卫,我终于弄清楚了代码是如何工作的。我已经在您的评论区实现了一个显示通知方法。但是,有一件事我不太明白。如果我希望应用程序在“(now-firstDetectionTime > 30000l)”时显示通知,那么在 30 秒后,通知后会有通知。如果我将其更改为 (now-firstDetectionTime = 30000l),则不会出现任何通知。这是为什么?如何确保通知只显示一次?
    • 使代码只执行一次的最简单方法是添加一个新的 HashSet 来存储是否已经为特定信标触发了事件:HashSet&lt;String&gt; beaconEventsFired = new HashSet&lt;String&gt;(); 然后在触发事件之前将代码包装在 @ 987654324@
    • 谢谢!!我尝试添加您提供的代码,它说找不到符号方法get(boolean),它指的是beaconEventsFired.get(),我该怎么办?
    猜你喜欢
    • 2021-10-13
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多