绑定 beaconmanager 时在后台启动应用程序

Starting app in background when beaconmanager is bound

我无法在输入的区域显示我的应用程序,我遵循了示例 here。 当我不 bind BeaconManager 到我的 Activty 时它工作,但是当我这样做时,我从 Activity 获取日志而不是从应用程序获取日志,并且应用程序没有显示,尽管它不可​​见.

所以问题是,我可以使用 class extends Application implements BootstrapNotifier 在后台启动应用程序并使用 class extends AppCompatActivity implements BeaconConsumer 来处理 monitoring/ranging 或者我是否需要处理应用程序 class 中的所有内容,因为在 activity 中绑定它会导致后台启动失败?

(抱歉代码块不好,我无法正确处理这个 Whosebug 代码)

    public class BeaconActivity extends AppCompatActivity implements BeaconConsumer {

    protected final String TAG = "BeaconActivity";
    private BeaconManager beaconManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate()");
        setContentView(R.layout.activity_beacon);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

       RangedBeacon.setSampleExpirationMilliseconds(8000);
       beaconManager = BeaconManager.getInstanceForApplication(this);
       beaconManager.bind(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Unbind Beaconmanager");
        beaconManager.unbind(this);
    }

    @Override
    public void onBeaconServiceConnect() {
        beaconManager.setMonitorNotifier(new MonitorNotifier() {
            @Override
            public void didEnterRegion(final Region region) {
                Log.d(TAG, "Enter Region identifier: " + region.getId1() + ", " + region.getId2() + ", " + region.getId3());
            }

            @Override
            public void didExitRegion(final Region region) {
                Log.d(TAG, "Exit Region identifier: " + region.getId1() + ", " + region.getId2() + ", " + region.getId3());
            }

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

            }
        });

        beaconManager.setRangeNotifier(new RangeNotifier() {
            @Override
            public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
                for (final Beacon beacon : beacons) {
                    final String distance = new DecimalFormat("##.######").format(beacon.getDistance());
                    Log.d(TAG, "Distance: " + distance + ". This beacon has identifiers:" + beacon.getId1() + ", " + beacon.getId2() + ", " + beacon.getId3());
                }
            }
        });

        try {
            Region region = new Region("all", null, null, null);
            beaconManager.startMonitoringBeaconsInRegion(all);
            beaconManager.startRangingBeaconsInRegion(all);
        } catch (RemoteException e) {
        }
    }
}



public class BeaconApplication extends Application implements BootstrapNotifier {

        private static final String TAG = "BeaconApplication";
        private RegionBootstrap regionBootstrap;

        @Override
        public void onCreate() {
            super.onCreate();
            Log.d(TAG, "App started up");
            BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
            beaconManager.getBeaconParsers().add(new BeaconParser().
                    setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));

            Region all = new Region("all", null, null, null);
            regionBootstrap = new RegionBootstrap(this, all);
        }

        @Override
        public void didEnterRegion(Region region) {
            Log.d(TAG, "Enter region " + region.getUniqueId());
    //        regionBootstrap.disable();
            Intent intent = new Intent(this, BeaconActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            this.startActivity(intent);
        }

        @Override
        public void didExitRegion(Region region) {
            Log.d(TAG, "Exit region " + region.getUniqueId());
        }

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

编辑: 我想我可能只是搞砸了一点。解释 here 应用程序只有在被杀死时才会启动(不再在任务切换器中)。如果它在任务切换器中可用,它只会在后台处理传入的事件,这就是我得到 activity 日志的原因。

问题是您的申请只能有一个 monitorNotifierRegionBootstrap class 在内部设置一个,并使用它来获取对 Application class.

的回调

上面显示的代码更改了此处的 monitorNotifier

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

该行执行后,RegionBootstrap 将不会再获得任何关于 entry/exit 事件的回调,Application class 也不会。所以问题不在于 bind() 调用,而是 setMonitorNotifier 调用。

该库不允许多个 monitorNotifiers,因此如果您想继续使用 RegionBootstrap,您必须重构您的代码,以便获得所有 entry/exit 事件您的应用程序 class 并以某种方式将它们传递给您的 Activity.