Using AltBeacon: start and stop scanning from app settings

♀尐吖头ヾ 提交于 2019-12-23 02:54:13

问题


I am integrating the AltBeacon API in an existing app. The app shall start actions in the background, when the user enters or leaves a "bluetooth zone".

This functionality should be optional and the user should start and stop the scanning from the settings.

I tryed bind/unbind the BeaconConsumer, but I saw, that in the background the BluetoothLeScanner is keeping scanning! How can I stop the BluetoothLeScanner from scanning? Is this the right way?

Here is the code:

@Override
    public void onCreate() {
        super.onCreate();
        LogManager.setVerboseLoggingEnabled(true);
        log.debug("onCreate");
        mAllBeaconsRegion = new Region(ALLBEACONS, null, null, null);
        mBeaconManager = BeaconManager.getInstanceForApplication(this);
        mBackgroundPowerSaver = new BackgroundPowerSaver(this);
        mBeaconManager.setBackgroundBetweenScanPeriod(60000L);
        mBeaconManager.setBackgroundScanPeriod(2100L);
        // wake up the app when a beacon is seen
        mRegionBootstrap = new RegionBootstrap(this, mAllBeaconsRegion);
        mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
        dsGlobal = new DbGlobalsHelper(getApplicationContext());
        boolean isBeaconScan = Utils.isBoolean(dsGlobal.getCursorGlobalsByKey(Constants.DB_KEY_BEACON_SCAN));
        if(isBeaconScan){
            mBeaconManager.bind(this);
        }else{
            mBeaconManager.unbind(this);
        }
    }

    // Set Regions to monitor at boot/startup
    private void setRegionsAtBoot(){
        Log.i(TAG, "setRegionsAtBoot");
        log.info("setRegionsAtBoot");
        SimpleBeaconStore beaconStore = new SimpleBeaconStore(this);
        List<SimpleBeacon> beacons = beaconStore.getBeacons();
        for (Iterator<SimpleBeacon> iterator = beacons.iterator(); iterator.hasNext();) {
            SimpleBeacon simpleBeacon = iterator.next();
            List<Identifier> listB = new ArrayList<Identifier>();
            StringTokenizer st = new StringTokenizer(simpleBeacon.getBeaconUuid(), "#");
            while (st.hasMoreTokens()) {
                listB.add(new Identifier(Identifier.parse(st.nextToken())));
            }
            try {
                Log.i(TAG, "setRegionsAtBoot " + simpleBeacon.getId());
                log.info("setRegionsAtBoot " + simpleBeacon.getId());
                Region region = new Region(simpleBeacon.getId(), listB);
                mBeaconManager.startRangingBeaconsInRegion(region);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
        // Start actions
        if (region.getUniqueId().equals(ALLBEACONS)){
            return;
        }
        if (beacons.size() > 0) {
            for (Beacon beacon: beacons) {
                Log.d(TAG, "Beacon "+beacon.toString()+" is about "+beacon.getDistance()+" meters away, with Rssi: "+beacon.getRssi());
                log.debug("Beacon " + beacon.toString() + " is about " + beacon.getDistance() + " meters away, with Rssi: " + beacon.getRssi());

                datasource = new DbZoneHelper(getApplicationContext());
                ZoneEntity ze = datasource.getCursorZoneByName(region.getUniqueId());

                if (beacon.getDistance() < ze.getRadius() && !ze.isStatus()) {
                    // 
                    Log.i(TAG, "Beacon " + beacon.toString() + " Just became less than " + ze.getRadius() + " meters away.");
                    log.info("*** Beacon " + beacon.toString() + " Just became less than " + ze.getRadius() + " meters away. ***");
                    String transitionType = getTransitionString(1);
                    NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());
                    worker = new Worker(getApplicationContext());
                    worker.handleTransition(1, region.getUniqueId(), Constants.BEACON);

                }
                if (beacon.getDistance() > (ze.getRadius() * EXITMULTIPLICATOR) && ze.isStatus()) {
                    // 
                    Log.i(TAG, "Beacon "+ beacon.toString()+" Just became over " + ze.getRadius() * EXITMULTIPLICATOR + " meters away.");
                    log.info("*** Beacon " + beacon.toString() + " Just became over " + ze.getRadius() * EXITMULTIPLICATOR + " meters away. ***");
                    String transitionType = getTransitionString(2);
                    NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());

                    worker = new Worker(getApplicationContext());
                    // 
                    worker.handleTransition(2, region.getUniqueId(), Constants.BEACON);

                }
            }
        }
    }

    @Override
    public void didDetermineStateForRegion(int arg0, Region arg1) {
    }

    @Override
    public void didEnterRegion(Region region) {

    }

    @Override
    public void didExitRegion(Region region) {

        if (region.getUniqueId().equals(ALLBEACONS)){
            return;
        }

        datasource = new DbZoneHelper(getApplicationContext());
        ZoneEntity ze = datasource.getCursorZoneByName(region.getUniqueId());

        if (ze.isStatus()) {
            // 
            Log.i(TAG, "Beacon " + region.getUniqueId() + " Just exited region.");
            log.info("Beacon " + region.getUniqueId() + " Just exited region.");
            String transitionType = getTransitionString(2);
            NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());

            worker = new Worker(getApplicationContext());

            worker.handleTransition(2, region.getUniqueId(), Constants.BEACON);
        }
    }

    @Override
    public void onBeaconServiceConnect() {
        Log.d(TAG, "onBeaconServiceConnect.");
        log.debug("onBeaconServiceConnect");
        setRegionsAtBoot();
        mBeaconManager.setRangeNotifier(this);
    }

    public void bind(){
        mBeaconManager.bind(this);
    }

    public void unbind(){
        mBeaconManager.unbind(this);
    }

I am also calling the bind/unbind from my settings.


回答1:


The code shown uses a RegionBootstrap class to continually scan for beacons in the background. This class is essentially designed to never stop scanning for beacons. The RegionBootstrap binds to the scanning service when constructed and effectively never unbinds. The code shown that manually binds and unbinds therefore has no effect.

If you want to start and stop scanning at various times, then don't use the RegionBootstrap class, and instead make your Application or Activity implement BeaconConsumer and bind/unbind as described in the monitoring example code here: http://altbeacon.github.io/android-beacon-library/samples.html



来源:https://stackoverflow.com/questions/33826703/using-altbeacon-start-and-stop-scanning-from-app-settings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!