Intereting Posts

Android AltBeacon Фоновая служба Ranging

Я работаю над приложением bluetooth, используя библиотеку AltBeacon. Кажется, что только для приложения BeaconManager допускается только одно приложение. Проблема, с которой я столкнулся, заключается в следующем: я хочу постоянно работать в фоновом режиме, который постоянно выполняет настройку bluetooth и отправляет уведомления. Если я открою свое приложение (принесу его на передний план), я был сервисом для паузы. Затем передняя активность будет выполнять ранжирование и показывать содержимое на экране.

Проблема в том, что диспетчер маяков (от BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this); ) в BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this); и сервисе – это тот же самый экземпляр. Поэтому, когда активность закрывается, beaconManager.unbind(this); Вызывается, а уведомитель диапазона в службе больше не срабатывает.

Можно ли получить два отдельных экземпляра маякового менеджера? Если нет, как я могу это сделать в непрерывном режиме работы и активности?

RangingActivity

 @Override protected void onCreate(Bundle savedInstanceState) { ... regionEstimote = new Region("estimote", null, null, null); beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")); beaconManager.bind(this); } @Override protected void onDestroy() { super.onDestroy(); notificationManager.cancel(NOTIFICATION_ID); //beaconManager.unbind(this); } @Override public void onBeaconServiceConnect() { beaconManager.setRangeNotifier(new RangeNotifier() { .... }); try { beaconManager.startRangingBeaconsInRegion(regionEstimote); } catch (RemoteException e) { Log.e(TAG, "RangingActivity", e); } } 

BeaconService.java

 @Override public int onStartCommand(Intent intent, int flags, int startId) { if(beaconHistory == null) beaconHistory = new HashMap<Integer, Date>(); mBeaconManager = BeaconManager.getInstanceForApplication(this); mBeaconManager.getBeaconParsers().add(new BeaconParser(). setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")); return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); beaconHistory = null; mBeaconManager.unbind(this); } @Override public void onBeaconServiceConnect() { mBeaconManager.setRangeNotifier(new RangeNotifier() { @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if(ActivityBase.isActivityVisible()) { //don't do ranging logic if any activity from my app is in the foreground return; } ... } }); try { mBeaconManager.startRangingBeaconsInRegion(regionMint); } catch (RemoteException e) { Log.e(TAG, "BeaconService", e); } } 

Solutions Collecting From Web of "Android AltBeacon Фоновая служба Ranging"

Это случай, когда пользовательский класс android.app.Application очень полезен. BeaconManager – синглтон, поэтому только один из них может существовать одновременно. Аналогично, класс Application имеет один экземпляр для активного приложения Android. Если вы хотите выполнять обнаружение маяка в Activity и Service одновременно, используйте централизованный класс Application для привязки к BeaconManager а затем переадресуйте обратные вызовы как для своей Activity и для вашей Service .

Вы можете увидеть пример привязки к BeaconManager в классе Application а затем передать обратные вызовы в Activity в ссылочном приложении: https://github.com/AltBeacon/android-beacon-library-reference/blob/master/app /src/main/java/org/altbeacon/beaconreference/BeaconReferenceApplication.java

Вы должны расширить класс Applicaton и запустить фоновый мониторинг региона, как это описано здесь (см. «Запуск приложения в фоновом режиме»).

Чтобы выполнить ранжирование, в том же классе реализуйте RangeNotifier:

 public class AndroidApp extends Application implements BootstrapNotifier, RangeNotifier {... 

Начать ранжирование в didEnterRegion:

 @Override public void didEnterRegion(Region region) { try { mBeaconManager.startRangingBeaconsInRegion(region); } catch (RemoteException e) { if (BuildConfig.DEBUG) Log.d(Const.TAG, "Can't start ranging"); } } 
  1. Реализовать метод didRangeBeaconsInRegion:

     @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if (beacons.size() > 0) { Beacon firstBeacon = beacons.iterator().next(); if (BuildConfig.DEBUG) Log.d(Const.TAG, "Beacon ranged: UUID: " + firstBeacon.getId1().toString() + " Major: " + firstBeacon.getId2().toString() + " Minor: " + firstBeacon.getId3().toString()); // Do something with the result // Stop ranging try { mBeaconManager.stopRangingBeaconsInRegion(region); } catch (RemoteException e) { e.printStackTrace(); } } }