0

Я пытаюсь уведомить пользователя, когда пользователь входит в определенную область, а также когда пользователь выходит из региона. Это то, что я сделал до сих пор. Я использовал метод rangeNotifier (didBeaconsEnterRange), чтобы уведомить пользователя, когда он/она входит в регион, но затем этот метод будет вызываться каждые 1 секунду, поэтому я переместил логику уведомлений методу monitorNotifier class (didEnterRegion).Beacons didEnterRegion и didExitRegion неоднократно вызывались

Мой класс приложения расширяет BootStrapNotifier, и я устанавливаю scanPeriod на 2000 секунд вместо стандартных 1100 секунд, потому что я, кажется, слишком быстро получаю уведомления о выходе и записи, даже когда маяк находится в зоне действия. Раньше я даже увеличивал период ожидания от 10000 мс до 20000 мс, который срабатывал бы, когда маяк не срабатывал в течение периода ожидания.

Фрагмент кода для MyApplication класса

BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this); 
    beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(LAYOUT_HERE)); 
    beaconManager.setForegroundScanPeriod(2000l); 
    beaconManager.setBackgroundBetweenScanPeriod(1100l); 
    //beaconManager.setBackgroundScanPeriod(5000l); 
    beaconManager.setDebug(true); 

    Log.d(TAG, "setting up background monitoring for beacons and power saving"); 
    // wake up the app when a beacon is seen 
    mRegion = new Region("myRangingUniqueId", 
      null, null, null); 
    setRegionAgain(); 

метод SetRegionAgain

if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0) { 
     if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0) { 
      try { 
       mRegion = new Region("myRangingUniqueId", 
         Identifier.parse(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "")), 
         null, null); 
      }catch(IllegalArgumentException e) { 
       e.printStackTrace(); 
       mRegion = new Region("myRangingUniqueId", 
         null, null, null); 
      } 
     } 
    } 

    regionBootstrap = new RegionBootstrap(this, mRegion); 

    // simply constructing this class and holding a reference to it in your custom Application 
    // class will automatically cause the BeaconLibrary to save battery whenever the application 
    // is not visible. This reduces bluetooth power usage by about 60% 
    backgroundPowerSaver = new BackgroundPowerSaver(this); 

У меня есть фоновый сервис, который делает работу уведомления, поэтому он реализует интерфейс BeaconConsumer. Фрагмент кода ниже:

OnStart метод:

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    flagToCheckExit = false; 
    mHandler = new Handler(); 
    beaconManager.bind(this); 
    if (beaconManager.isBound(this)) beaconManager.setBackgroundMode(false); 
    return Service.START_STICKY; 
} 

метод OnDestroy:

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    try { 
     beaconManager.stopMonitoringBeaconsInRegion(CommonUtilities.getRegion()); 
// this region is the one that i use to monitor (singleton types) 
    } catch (RemoteException e) { 
     e.printStackTrace(); 
    } 

    beaconManager.unbind(this); 
} 

onServiceConnected метод:

@Override 
public void onBeaconServiceConnect() { 
    beaconManager.setMonitorNotifier(new MonitorNotifier() { 

     @Override 
     public void didExitRegion(final Region region) { 
      LogManager.d(TAG, "didExitRegion %s", region); 

      if(SharedPrefs.getString(SharedPrefs.USER_ID, "").trim().length() > 0) { 
       flagToCheckExit = true; 
// i use this flag to prevent random entry and exit notifications 
       mHandler.postDelayed(mRunnable, 20000); 
// waiting for 20seconds before firing an exit notification, since an entry notification might get fired immediately after the exit 
      } 
     } 

     @Override 
     public void didEnterRegion(Region region) { 
      Log.e(TAG,"region id1 >>> " + ((region.getId1() == null) ? "null" : region.getId1().toUuidString())); 

      LogManager.d(TAG, "didEnterRegion %s ",region); 

      if(!flagToCheckExit) { 
       if(SharedPrefs.getString(SharedPrefs.USER_ID, "").trim().length() > 0) { 
        if(region.getId1() != null && 
          region.getId1().toUuidString().equalsIgnoreCase(SharedPrefs.getString(SharedPrefs.iBEACON_ID, ""))) { 
         if(!SharedPrefs.getBoolean(SharedPrefs.IS_ENTRY_LOG_CALLED, false)) { 
          String entryRange = getAppContext().getString(R.string.entered_beacon_region); 
        CommonUtilities.sendNotification(MonitoringAltBeaconService.this,entryRange,1); 
         } 
        } 
       } 
      }else { 
       // invalidate the handler 
       // stop all operations of the handler 
       // we do this to prevent an exit getting called since entry has been called immediately. 
       mHandler.removeCallbacks(mRunnable); 
      } 
     } 

     @Override 
     public void didDetermineStateForRegion(int state, Region region) { 
      LogManager.d(TAG, "didDetermineStateForRegion %s ",region); 
     } 
    }); 

    startMonitoring(); 
} 

метод startMonitoring:

private void startMonitoring() { 
    try { 
     if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0) { 
      try { 
       beaconManager.startMonitoringBeaconsInRegion(CommonUtilities.getRegion()); 
      }catch(IllegalArgumentException e) { 
       e.printStackTrace(); 

       beaconManager.startMonitoringBeaconsInRegion(CommonUtilities.getRegion()); 
      } 
     } 
    } catch (RemoteException e) { } 
} 

с выполняемой нитью:

Runnable mRunnable = new Runnable() { 
    @Override 
    public void run() { 
     SharedPrefs.putBoolean(SharedPrefs.IS_ENTRY_LOG_CALLED, false); 
     SharedPrefs.putBoolean(SharedPrefs.IS_EXIT_LOG_CALLED, true); 

     String exitedRange = getAppContext().getString(R.string.exited_beacon_region); 
     CommonUtilities.sendNotification(MonitoringAltBeaconService.this,exitedRange,2); 
     LogManager.d(TAG, "exit called"); 
     flagToCheckExit = false; 
    } 
}; 

Существует странное поведение с этим, существует несколько входа и выход журналов, которые я получаю, даже когда устройство маяка находится в диапазоне, я получаю выход. Я пробовал обходить уведомление о выходе, но, похоже, с ошибкой (patch) выше.

Log:

03-19 18:00:25.866: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:00:25.867: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:00:26.470: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 

03-19 18:00:26.477: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 

03-19 18:00:48.076: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:00:48.076: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 

03-19 18:00:51.275: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:00:51.282: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:01:10.269: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:01:10.269: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:01:15.876: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:01:15.883: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 

Я использую AprilBeacon. Приложение, над которым я работаю, задерживается, потому что маяки не генерируют уведомления правильно. Пожалуйста помогите.

EDIT:

устройство я использую, если Motorolla g2, этот сценарий происходит в обоих KitKat, а также версии леденец. И Wi-Fi включен, я предпочитаю, чтобы он был включен, так как в нем задействованы вызовы webservice, когда определяется вход. В режиме реального времени не рекомендуется просить пользователей отключать Wi-Fi :(..

Библиотека, которую я использую, представляет собой андроид-маяк-библиотеку here, и я боюсь, что не знаю частоты, с которой маяк маяка посылает сигналы.

EDIT 2:

Вход 1 можно найти here

Log 2 можно найти here

EDIT 3

log when wifi is switched off я заметил, что я сделал получаю выход, даже когда маяк находился в диапазоне И Я открыл приложение локации, и он показал, что никаких маяков нет (см. снимок экрана). я удалил батарею и положил ее обратно, она получила маяк, а также мое приложение тоже. (Но в реальной жизни, я уверен, что батареи не будут подделаны)

When not detected After removing the batteries

+0

Я понимаю, что не хочу отключать WiFi, но можете ли вы попробовать это как шаг устранения неполадок и сообщить нам, не имеет значения? Это поможет устранить проблему. – davidgyoung

ответ

1

Ваша конфигурация, кажется, действительно, но есть небольшой недостаток. Вы должны установить оба переднего плана конфиги сканирования:

beaconManager.setForegroundScanPeriod(2000l); 
beaconManager.setForegroundBetweenScanPeriod(1100l); 
//Update default time with the new one 
beaconManager.updateScanPeriods(); 

или/и фоновой проверки конфиги:

beaconManager.setBackgroundScanPeriod(2000l); 
beaconManager.setBackgroundBetweenScanPeriod(1100l); 
//Update default time with the new one 
beaconManager.updateScanPeriods(); 

Кроме того, знаете ли вы рекламную частоту маяка? Вы сказали, что у вас увеличен период сканирования до 20 секунд, и ничто не изменилось, частота будет полезна для нас, чтобы помочь вам.

Btw, вы также можете делиться выходами Logcat от AltBeacon? Кроме того, каково ваше устройство и модель? И какая версия Android работает? И какую версию библиотеки AltBeacon вы используете?

Если устройство работает Lollipop попробуйте следующую строку и, пожалуйста, поделитесь с нами результатами:

BeaconManager.setAndroidLScanningDisabled(true); 

Кроме того, попробуйте с поворотом вашего Wi-Fi, если он включен, потому что в некоторых устройствах это мешает сканирование Bluetooth.

Btw, извините, это больше похоже на комментарий, чем на ответ, но он тоже должен был оставить комментарий :).

+0

Пожалуйста, проверьте изменения в вопросе. Мне нужно некоторое время, прежде чем я смогу опубликовать журналы AltBeacon. я просто пропустил запись журналов. –

+0

Можете ли вы протестировать, выключив Wi-Fi? Я знаю на самом деле, вы не можете предположить, что Wi-Fi отключен или заставить пользователя отключить его, но, по крайней мере, мы можем быть уверены в этом. Кстати, на самом деле я спрашивал, какую версию AltBeacon Library вы используете. Извините за недопонимание. –

+0

привет, откуда я могу получить версию? его нет где в папках. Я загрузил его неделю назад. –

0

EDIT: после просмотра журналов я представил другой ответ, который лучше отвечает на вопрос. Пожалуйста, см. Этот ответ.

Я заметил из двух опубликованных журналов, что библиотека сообщает, что приложение находится в фоновом режиме и использует API Android L. Это заставляет их использовать «Low Latency» обнаружения:

03-26 15:47:21.647: D/CycledLeScannerForLollipop(28596): This is Android L. Doing a filtered scan for the background. 

Низких обнаружений задержки экономию энергии, но они получают с задержкой в ​​5 секунд или более. Это отлично работает для фоновых операций, но не предназначено для операций переднего плана и должно использоваться с интервалами сканирования по умолчанию. Вы не должны устанавливать ненулевое значение между интервалом сканирования при использовании этих API Andorid L, иначе вы можете получить выходы, как вы описываете.

Если журналы ошибочно сообщают, что ваше приложение находится в фоновом режиме, может быть что-то не в порядке с настройкой BackgroundPowerSaver.

Вы также можете попробовать отключить API Android L и использовать старые API-интерфейсы сканирования 4.x, чтобы узнать, работает ли это лучше для вашего случая использования. Если вы сделаете это, я хотел бы также удалить какие-либо специальные настройки интервала сканирования так, чтобы не сделать конфигурацию слишком сложной:

beaconManager.setAndroidLScanningDisabled(true) 

Вам нужно будет поставить эту строку в onCreate вашего класса приложения, прежде чем сделать какой-либо другой маяк обработка.

+0

Сэр, да, это правда, что приложение находится в фоновом режиме, так как это один из тестовых примеров, поэтому журнал не сообщает ничего неправильного. :) .. 'Вы никогда не должны устанавливать ненулевое значение между интервалом сканирования при использовании этих API Andorid L, иначе вы можете получить выходы, как вы описываете' - это относится к фоновому сканированию, если я установил его на нулевой интервал, будет слить аккумулятор? –

+0

Извините, пожалуйста, проигнорируйте мое заявление о ненулевом интервале между интервалами сканирования, которое применяется только к предварительно выпущенной версии поддержки Android L. См. Мой другой ответ. – davidgyoung

1

Проблема заключается в сочетании редко встречного маяка и пользовательского интервала фонового сканирования, который слишком короткий.

Похоже, что маяк рекламируется только раз в 2 сек., потому что это самый близкий я когда-либо видел две последующие метки времени регистрации в журнале. Это низкая частота передачи является проблематичной и усугубляется пользовательскими настройками.

Для правильной работы библиотеки период сканирования фона должен быть не менее 5x периода передачи маяка. Это связано с тем, что не все пакеты bluetooth получают из-за радиошумов. Имея интервал, равный 5 раз, период передачи означает, что есть 5 шансов получить пакет в каждом цикле фонового сканирования, что делает его очень маловероятным, что библиотека пропустит один.

Настройки библиотеки по умолчанию устанавливают период сканирования фона на 10 секунд, что должно быть достаточным, чтобы обеспечить высокую вероятность обнаружения даже маякового радиосигнала только один раз каждые 2 секунды и сделать неправильную область выхода очень и очень редко.

Рекомендации:

  1. Изменить фоновый период сканирования, чтобы быть по крайней мере, по умолчанию 10 секунд. Чтобы сэкономить аккумулятор, период между сканированием, вероятно, должен быть длиннее - по умолчанию 5 минут является разумным выбором, если у вас нет веских оснований для его сокращения. Если вы все еще получаете события выхода, сделайте период сканирования фона еще длиннее.

  2. Используйте различные маяки, которые рекламируют более часто. Несмотря на то, что вы должны иметь возможность работать с этими маяками, вы не будете получать обновления так часто, и такие приложения, как Locate, будут периодически показывать выпадения в обнаружении. Если вы делаете оценки расстояния в своем приложении, вам нужны маяки, которые передают с частотой 10 Гц или более. Если вы не делаете оценки расстояния в своем приложении, вы все равно должны использовать маяки, которые передают с частотой 1 Гц или более, иначе у вас будут более вероятные проблемы, подобные этому.

Как узнать, что это проблема?

Как вы можете видеть из приведенных ниже отрывков журнала, неправильный выход области происходит в 15:50:52, потому что прошло 10 секунд с момента предыдущего обнаружения. Любой 10-секундный период без обнаружения вызовет событие выхода из области в следующий раз, когда цикл сканирования остановится. Поэтому вы должны быть уверены, что цикл сканирования достаточно длинный, чтобы захватить передачу маяка. С помощью пользовательских настроек отсутствие обнаружения в течение трех последующих циклов сканирования приведет к выходу из региона.

03-26 15:49:49.533: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:49:55.567: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:01.624: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:08.898: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:11.315: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:17.380: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:21.010: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:26.440: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:30.066: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:33.108: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:36.120: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:39.745: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:41.573: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 

03-26 15:50:52.415: D/MonitorState(28596): We are newly outside the region because the lastSeenTime of 1427365241573 was 10841 seconds ago, and that is over the expiration duration of 10000 
03-26 15:50:52.415: D/BeaconService(28596): found a monitor that expired: id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-26 15:50:52.415: D/Callback(28596): attempting callback via intent: ComponentInfo{com.credencys.mycarline/org.altbeacon.beacon.BeaconIntentProcessor} 

03-26 15:50:54.879: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:50:56.705: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:51:00.940: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:51:03.348: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7 
03-26 15:51:03.349: D/BeaconService(28596): looking for ranging region matches for this beacon 
03-26 15:51:03.842: D/CycledLeScanner(28596): Waiting to stop scan cycle for another 1000 milliseconds 
03-26 15:51:04.730: D/MonitoringAltBeaconService(28596): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
+0

сэр, я немного смущен. BootsrapNotifier, я реализую это в классе приложения или моей службе? –

+0

BootsrapNotifier предназначен для реализации пользовательским классом приложений. – davidgyoung

+0

поэтому, если я создаю область в классе приложения, а затем создаю регион с конкретным uuid после входа в систему, то в классе приложения будет переопределен? Кроме того, будет ли служба получать вызов didEnter или класс приложения замачивается в вызове didEnter? –

Смежные вопросы