Я пытаюсь уведомить пользователя, когда пользователь входит в определенный регион, а также когда пользователь выходит из региона. Это то, что я сделал до сих пор. Раньше я использовал метод rangeNotifier (didBeaconsEnterRange), чтобы уведомлять пользователя, когда он/она входит в регион, но тогда этот метод вызывался каждую секунду, поэтому я перенес логику уведомления в метод класса monitorNotifier (didEnterRegion).
Мой класс приложения расширяет 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;
}
};
При этом наблюдается странное поведение, есть несколько журналов входа и выхода, которые я получаю, даже когда устройство маяка находится в пределах досягаемости, я получаю выход. Я попытался обойти уведомление о выходе, но, похоже, это не работает с логикой (исправлением) выше.
Журнал:
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
Я использую Эйприл Бикон. Приложение, над которым я работаю, задерживается, потому что маяки неправильно генерируют уведомления. Пожалуйста помогите.
ИЗМЕНИТЬ:
устройство, которое я использую, если Motorolla g2, этот сценарий происходит как в версии kitkat, так и в версии леденца. И Wi-Fi включен, я предпочитаю, чтобы он был включен, поскольку при определении входа и выхода задействованы вызовы веб-сервиса. В реальном времени не рекомендуется просить пользователей выключить Wi-Fi :(..
Я использую библиотеку android-beacon-library здесь, и я Боюсь, я не знаю, на какой частоте апрельский маяк посылает сигналы.
РЕДАКТИРОВАТЬ 2:
Журнал 1 можно найти здесь
Журнал 2 можно найти здесь
ИЗМЕНИТЬ 3
журнал при выключенном Wi-Fi Я заметил, что получил выход, даже когда маяк был включен диапазон И я открыл приложение для поиска, и оно показало, что маяков нет (см. Скриншот). я вынул аккумулятор и вставил их обратно, он получил маяк, и мое приложение тоже. (но в реальной жизни я уверен, что батареи не будут подделаны)