【问题标题】:Android Beacon Library restart monitoring, dynamic regionsAndroid Beacon Library 重启监控,动态区域
【发布时间】:2016-04-06 09:16:58
【问题描述】:

首先,如果您发现一些错误,请原谅我的英语并感谢您的帮助。我有一个程序使用 API REST 服务来检索区域列表以每隔 X 秒监控一次。我正在使用 Android 信标库来监控区域,我希望能够停止监控这些区域,获取新列表,然后开始监控新区域。到目前为止,我有这个代码(简化):

public class MainActivity extends Activity implements BeaconConsumer {
  // Code
  Timer task = new TimerTask() {
    @Override
    public void run() {
      handler.post(new rRunnable() {
        @Override
        public void run() {
          new MyAsyncTask().execute(some_params);
        }
      });
    }
  }

  @Override
  protected void onCreate(Buncle savedInstanceState) {
    // Code
    beaconManager = BeaconManager.getInstanceForApplication(this);
    // Set parsers (iBeacon, Eddystone-UID, Eddystone-URL)
    beaconManager.bind(this);
    Log.i(TAG, "Using Android Beacon Library version: "+ org.altbeacon.beacon.BuildConfig.VERSION_NAME);
  }

  @Override
  public void onBeaconServiceConnect() {
    @Override
    public void didEnterRegion(Region region) {
      // Get info of regions and show a list of regions detected on UI
      Log.i(TAG, "Inside of: " + region.toString());
    }

    @Override
    public void didExitRegion(Region region) {
      // Get info of regions and show a list of regions detected on UI
      Log.i(TAG, "Outside of: " + region.toString());
    }

    @Override
    public void didDetermineStateForRegion(int state, Region region) {
      Log.i(TAG, "State: " + state);
    }

    // execute async task to stop monitoring, get new regions list and then
    // start monitoring again
    timer.schedule(task, 0, 30000); 
  }

  private class MyAsyncTask extends AyncTask<String, Void, List<Region>> {
    @Override
    protected List<Region> doInBackground(String... params) {
      // Get list of regions from server
    }

    @Override
    protected void onPostExecute(List<Region> result) {
      // For loop to stop monitoring all regions
      for (Region region : beaconManager.getMonitoredRegions()) {
        try {
          beaconManager.stopMonitoringBeaconsInRegion(region);
          Log.i(TAG, "Stop monitoring: " + region.toString());
        } catch (RemoteException e) { }
      }
      Log.i(TAG, "Nº of regions: " + beaconManager.getMonitoredRegions().size());
      // For loop to start monitoring new regions
      for (Region region : result) {
        try {
          beaconManager.startMonitoringBeaconsInRegion(region);
          Log.i(TAG, "Start monitoring: " + region.toString());
        } catch (RemoteException e) { }
      }
      Log.i(TAG, "Nº of regions: " + beaconManager.getMonitoredRegions().size());
    }
  }

代码中没有语法错误,应用程序不会崩溃。当我执行应用程序时,它会调用服务器,获取要监控的区域列表,然后开始监控这些区域。然后,当信标在范围内时,屏幕上会显示受监控区域的列表。现在一切似乎都很好。然后,应用程序停止监控区域,请求新的区域列表并开始监控新的区域。我第一次尝试了 3 个区域,第二次尝试了 2 个,应用程序记录它开始监视 3 个区域,然后停止监视这 3 个区域,然后开始监视 2 个新区域。一切似乎都很好,但是虽然它说它开始监视新区域,但当信标在范围内时,该应用程序再也不会在屏幕上显示监视的区域。

我想知道问题是否出在我建立获取区域并监控它们的过程的方式上。

似乎在使用新区域重新启动监视后,它不会触发 didEnterRegion 和 didExitRegion。

编辑:我正在使用 3 个信标和 3 个区域测试该示例。第一个信标使用 iBeacon,第二个使用 Eddystone-UID,第三个使用 Eddystone-URL。每个区域都配置为检测一个特定的信标。

Logcat(简而言之,Beacon 和 Region 的 id 都是正确的):

Using Android Beacon Library version: 2.7
Nº of regions: 0
Start monitoring: id1: ibeacon_id id2: ibeacon_major id3: ibeacon_minor
Start monitoring: id1: eddystone_namespace id2: eddystone_id id3: null
Start monitoring: id1: eddystone_url id2: null id3: null
Nº of regions: 3
State: 1
Inside of: id1: eddystone_url id2: null id3: null
State: 1
Inside of: id1: eddystone_namespace id2: eddystone_id id3: null
State: 1
Inside of: id1: ibeacon_id id2: ibeacon_major id3: ibeacon_minor

30 seconds later (more or less)...
I have not changed the regions provided by the server.

Stop monitoring: id1: ibeacon_id id2: ibeacon_major id3: ibeacon_minor
Stop monitoring: id1: eddystone_namespace id2: eddystone_id id3: null
Stop monitoring: id1: eddystone_url id2: null id3: null
Nº of regions: 0
Start monitoring: id1: ibeacon_id id2: ibeacon_major id3: ibeacon_minor
Start monitoring: id1: eddystone_namespace id2: eddystone_id id3: null
Start monitoring: id1: eddystone_url id2: null id3: null
Nº of regions: 3

30 seconds later (more or less)...

Stop monitoring: id1: ibeacon_id id2: ibeacon_major id3: ibeacon_minor
Stop monitoring: id1: eddystone_namespace id2: eddystone_id id3: null
Stop monitoring: id1: eddystone_url id2: null id3: null
Nº of regions: 0
Start monitoring: id1: ibeacon_id id2: ibeacon_major id3: ibeacon_minor
Start monitoring: id1: eddystone_namespace id2: eddystone_id id3: null
Start monitoring: id1: eddystone_url id2: null id3: null
Nº of regions: 3

Keep repeating...

如我们所见,didEnterRegion、didExitRegion 和 didDetermineStateForRegion 事件不再触发。

【问题讨论】:

  • 您能确认您使用的是哪个库版本吗? Log.d(TAG, "Using Android Beacon Library version: "+org.altbeacon.beacon.BuildConfig.VERSION_NAME); 在重新启动监控区域的方法中,您能否添加显示 stopMonitoringBeaconsInRegion 和 startMonitoringBeaconsInRegion 调用的区域的日志语句,然后将日志语句输出附加到您的问题?了解您正在传输但不提供区域进入事件的信标的标识符也会很有帮助。
  • 我已经添加了日志信息,让代码更清晰了。
  • 顺便说一句,我已经测试了该应用程序,同时使用其他应用程序来检测信标(但不是与上述测试同时),例如 Locate、Beacon Manager 或 Estimote,以及当我执行其中一些时同时,最后没有检测到信标,直到我只留下其中一个扫描。这是正常行为吗?
  • 这是在后台还是前台?如果您等待 10 分钟,您仍然没有收到任何进入/退出事件吗?打开完整的调试日志并在 LogCat 中捕获大约 5 分钟可能会有所帮助。这将很大,因此您可以将其作为 Pastebin 或 Gist 链接。您可以使用 beaconManager.setDebug(true) 打开调试日志记录

标签: android android-asynctask beacon


【解决方案1】:

Android Beacon Library 中的 2.7 版本中存在一个未发现(直到现在)的错误,该错误会在停止扫描所有区域后停止在 Android 5+ 设备上的扫描。如果不从服务解除绑定并重新绑定到它,扫描将不会重新开始。

打开调试日志后,显示为:

04-11 08:35:07.655  D/BeaconService: stopMonitoring called
04-11 08:35:07.655  D/BeaconService: Currently monitoring 0 regions.
04-11 08:35:07.655  D/CycledLeScanner: stop called
04-11 08:35:07.655  D/CycledLeScanner: disabling scan
...
04-11 08:35:07.663  D/BeaconService: Currently monitoring 1 regions.
04-11 08:35:07.663  D/CycledLeScanner: start called
04-11 08:35:07.663  D/CycledLeScanner: scanning already started

在 2.8 版本中对其工作方式进行了更改,并且我已验证该错误在 2.8 中不再存在。 2.8版本下半部分是这样的:

04-12 18:15:07.623  D/BeaconService: Currently monitoring 1 regions.
04-12 18:13:06.938  D/CycledLeScanner: start called
04-12 18:13:06.938  D/CycledLeScanner: starting a new scan cycle
04-12 18:13:06.939  D/CycledLeScanner: starting a new bluetooth le scan

在 2.8 中,您可以停止监控所有区域,开始监控新区域,如果信标在附近,您将立即获得入口回调。简单的解决办法是升级到2.8,或者通过JCenter或者直接下载here.

【讨论】:

  • 我已经在不更改代码的情况下更新了库,现在它似乎可以正常工作了。日志显示:“I/BeaconService:停止收到监控”和“I/BeaconService:开始收到监控”。只是有一个小问题:现在它根本没有检测到信标 xD。 Beacon ID 一切正常,其他应用可以找到 Beacon。
  • 2.8 中的一个变化是该库在应用重新启动时会记住受监控区域的状态。因此,如果您停止应用程序并在信标仍在传输的情况下重新启动,您将不会收到额外的didEnterRegion 回调。这可能就是您所看到的。尝试关闭信标,等待退出,然后再次打开以获取进入事件。
  • 我正在使用 Estimote 睡眠模式,应用程序未检测到我是否要离开/进入这些区域。
  • 我不确定我是否理解。您是说当信标停止传输或移动设备离开附近时,您无法获取区域退出事件?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多