【问题标题】:Alt beacon lib continuously fires enter and exit region method where the user never left beacon zoneAlt beacon lib 持续触发用户从未离开信标区域的进入和退出区域方法
【发布时间】:2018-01-13 19:06:50
【问题描述】:

[### 预期行为

只有在信标实际退出该区域时,该库才应触发退出。

实际行为

lib 触发退出并进入信标仍在范围内的区域方法。在 5-7 的所有 android 版本上,这种情况每隔 20 秒发生一次,有时频率更高,有时频率更低

重现此行为的步骤

只要打开蓝牙,我就会在后台连续运行信标应用程序 打开搜索信标,信标固定在车内,并且以 1000 秒的间隔广播在用户从未离开信标区域的情况下连续报告信标进入和退出。

我的代码sn-p

public class BackgroundBeaconScan extends Service implements BootstrapNotifier, BeaconConsumer {
 @Override
    public void onCreate() {
        super.onCreate();
        AppUtils.isBGServiceActive = true;
        //AppUtils.appTerminated = false;
        Log.e("Beacon", "Service Start");
        Log.e("Bfpk", " *** Beacon  Service is started *** ");
        LoggingOperations logger = new LoggingOperations();
        Thread.setDefaultUncaughtExceptionHandler(logger);
        mBeaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
        try {
            Log.e("BG", "iam in mBeaconManager to unbind it");
            mBeaconManager.unbind(this);
            mBeaconManager.removeAllRangeNotifiers();
            mBeaconManager.removeAllMonitorNotifiers();
            mBeaconManager.removeMonitoreNotifier(this);
        } catch (OutOfMemoryError e) {
            Log.e("BG", "iam in mBeaconManager to unbind it excep ");

        }
    mBeaconManager.getBeaconParsers().clear();
    //set Beacon Layout for Eddystone-UID packet


    mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
    //   rideBDD = new RideBDD(getApplicationContext());
    mBeaconManager.setForegroundScanPeriod(20001);

    mBeaconManager.setForegroundBetweenScanPeriod(50001);

    mBeaconManager.setBackgroundScanPeriod(20001);

    mBeaconManager.setBackgroundBetweenScanPeriod(50001);

    mBeaconManager.setBackgroundMode(true);

    mBeaconManager.setDebug(true);

    BeaconManager.setAndroidLScanningDisabled(true);

    notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

    namespace = DataHandler.getStringPreferences(AppConstants.UUID_NAME_SPACE);
    instanceID = DataHandler.getStringPreferences(AppConstants.UUID_INSTANCE_ID);
    Log.e("BG", "namespace :" + namespace);
    Log.e("BG", "instanceID :" + instanceID);
    Long currentTime = System.currentTimeMillis();
    String time = formateLongToOnlyDateForServer(currentTime);
    LoggingOperations.writeToFile(BackgroundBeaconScan.this,"UUID > " + time + " -- > " + namespace + " - " + instanceID);



    try {
        Log.e("BG", "iam in mBeaconManager.isBound");
        mBeaconManager.bind(this);
        Log.e("BG", "iam in mBeaconManager.bind");

    } catch (OutOfMemoryError e) {
        Log.e("BG", "iam in mBeaconManager.bindexce", e);

    }


}

我的服务连接

@Override
    public void onBeaconServiceConnect() {
        // String preiBeaconUUID = DataHandler.getStringPreferences(AppConstants.UUID);
        // postiBeaconUUID=AppUtils.addDashes(preiBeaconUUID);
        Region region;
        try {
            Log.e("BG", "iam in onBeaconServiceConnect");
            namespace = DataHandler.getStringPreferences(AppConstants.UUID_NAME_SPACE);

            instanceID = DataHandler.getStringPreferences(AppConstants.UUID_INSTANCE_ID);

            Identifier myBeaconNamespaceId = Identifier.parse(namespace);

            Identifier myBeaconInstanceId = Identifier.parse(instanceID);

            region = new Region("EdstUIDAdvertising", myBeaconNamespaceId, myBeaconInstanceId, null);

            mBeaconManager.addMonitorNotifier(this);
            Log.e("BG", "iam in startMonitoringBeaconsInRegion");

        } catch (Exception e) {
            Log.e("BG", "iam in startMonitoringBeaconsInRegionExce" + e);
            e.printStackTrace();
            namespace = DataHandler.getStringPreferences(AppConstants.UUID_NAME_SPACE);

            instanceID = DataHandler.getStringPreferences(AppConstants.UUID_INSTANCE_ID);

            Identifier myBeaconNamespaceId = Identifier.parse(namespace);

            /* Identifier myBeaconInstanceId = Identifier.parse(instanceID);*/
            region = new Region("EdstUIDAdvertising", myBeaconNamespaceId, null, null);
            mBeaconManager.addMonitorNotifier(this);
            Log.e("BG", "iam in startMonitoringBeaconsInRegion");

        }
        AppUtils.isBGServiceActive = true;
        try {
            mBeaconManager.startMonitoringBeaconsInRegion(region);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        mBeaconManager.addMonitorNotifier(new MonitorNotifier() {
            @Override
            public void didEnterRegion(Region region) {
                Log.e("Monitored", "entered"); this fires at the same time
                enterCount++;

}

  @Override
            public void didExitRegion(Region region) {
                Log.e("Monitored", "exited"); // this fires at the same time

}

            @Override
            public void didDetermineStateForRegion(int i, Region region) {

            }
        });
}

移动设备型号和操作系统版本

Samsung note 5 (7.0) s6 (6.0) s5 (5.0) 每台设备

Android Beacon 库版本

2.12.4 // 请帮我解决这个问题很久了

【问题讨论】:

    标签: android bluetooth-lowenergy altbeacon background-service


    【解决方案1】:

    这是由间歇性检测信标引起的常见问题。了解图书馆仅在长时间未检测到信标时才知道信标何时消失(退出该区域)。如果在扫描周期结束时至少 10 秒内未看到先前看到的信标,则库将触发区域退出事件。

    建议:

    1. 将信标传输速率提高到 10 Hz 或更高。
    2. 如果您无法做到 (1),请将 scanPeriod 延长至更长,直到问题消失。

    示例代码中设置的自定义扫描周期可能会加剧您遇到的问题,其中显示了 5 秒的 scanPeriod 和 20 秒的 betweenScanPeriod。如果在 5 秒扫描期间未能检测到附近的信标。

    不清楚为什么有时在您配置的 5 秒扫描期间未检测到您的信标。可能它们只是不经常传输。一些信标仅每 5 秒左右发送一个广告数据包以节省电池电量。如果是这种情况,那肯定会导致您描述的问题。即使它们被设置为每秒传输一次,有时也可能由于无线电噪声而丢失连续 5 个数据包。

    如果您使用库的默认设置,则发生这种情况的可能性较小,因为扫描是在前台不断执行的(这使得在出口触发之前更有可能检测到信标)并在后台持续 10 秒。如果您不能或不想增加信标的广告率,我建议您将 scanPeriod / betweenScanPeriod 设置调整为每 30 秒超过 5 秒。

    为使磁带库正常运行,扫描周期必须至少是信标传输周期的 5 倍。这是因为并非所有蓝牙数据包都因无线电噪声而被接收。间隔是传输周期的 5 倍意味着在每个后台扫描周期有 5 次机会接收数据包,因此库不太可能错过一个

    【讨论】:

    • 谢谢大卫,那么在我的情况下,30s scan-p 和 10sec -btw-scan 所需的参数应该是什么?我将您的库与前台服务一起使用,它与后台服务的工作方式相同吗?在我的代码中,所有其他设置都很好还是有其他建议?由于我的罕见用例,考虑到我正在使用您的 lib 24/7。
    • 我会将高功率扫描限制在每天最多约 3000 秒以节省电池电量。如果将扫描周期设置为 10 秒,则扫描周期之间的间隔可以是 300 秒(300000 毫秒)。这相当于库的默认后台扫描间隔。
    • 谢谢,高倍扫描? mBeaconManager.setForegroundScanPeriod(300000L); mBeaconManager.setForegroundBetweenScanPeriod(300000L); mBeaconManager.setBackgroundScanPeriod(300000L); mBeaconManager.setBackgroundBetweenScanPeriod(150000L); mBeaconManager.setBackgroundMode(true);我使用了这些间隔,但仍然面临频繁的丢失,即使在 iBKS 工具配置上的信标处于活动状态的 20 分钟内没有检测到信标。如果您能给我一些我的用例的程序示例,我将开源我的扫描类以供其余部分使用:)
    • 如果您使用这些设置在 20 分钟内未检测到信标,则说明其他问题。您可以检查系统级别的日志消息,看看是否有任何东西阻止了您的扫描。
    • 感谢您的帮助大卫,PS 我不想打开另一个线程所以只是想知道你们是否正在计划 android O 并开发这个库的任何前台版本?我已经阅读您关于 O 的博客文章,但那是针对背景的,这对我们来说是不可行的,那么为什么我们不使用前台服务来获得准确的结果呢?谢谢。 P.S 在 android 7.0 中,当您关闭屏幕时,lib 会以默认扫描间隔触发退出方法,请检查一下。
    猜你喜欢
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多