Monitoring Listener detects only one beacon

I have 3 Estimote Beacons (Div Kit). In my Android app I’m trying to change 3 TextViews to show each beacon’s major and minor. I’ve changed the beacons settings to advertise signal every 1ms which is the shortest period of time.

The problem is that my BeaconManager object is detecting only one beacon and it takes a while to do that.

App.java

public class App extends Application {

    public static BeaconManager mBeaconManager;

    @Override
    public void onCreate() {
        super.onCreate();
        mBeaconManager = new BeaconManager(getApplicationContext());
        mBeaconManager.setBackgroundScanPeriod(TimeUnit.SECONDS.toMillis(1), 0);

        mBeaconManager.connect(new BeaconManager.ServiceReadyCallback() {
            @Override
            public void onServiceReady() {
                mBeaconManager.startMonitoring(new Region(
                        "monitored region",
                        UUID.fromString("B9407F30-F5F8-466E-AFF9-25556B57FE6D"),
                        null, null));
            }
        });
    }
}

MainActivity.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView tv = (TextView) findViewById(R.id.tv);
        final TextView tv2 = (TextView) findViewById(R.id.tv2);
        final TextView tv3 = (TextView) findViewById(R.id.tv3);

        App.mBeaconManager.setMonitoringListener(new BeaconManager.MonitoringListener() {
            @Override
            public void onEnteredRegion(Region region, List<Beacon> list) {
                tv.setText(list.get(0).getMajor() + " : " + list.get(0).getMinor());
                if (list.size() > 1) {
                    tv2.setText(list.get(1).getMajor() + " : " + list.get(1).getMinor());
                }
                if (list.size() > 2) {
                    tv3.setText(list.get(2).getMajor() + " : " + list.get(2).getMinor());
                }
            }

            @Override
            public void onExitedRegion(Region region) {
                tv.setText("Exit");
            }
        });
    }

That’s because you use beacon monitoring for only a single region—the “all beacons with the default Estimote UUID region”. This means that when your Android devices “hears” the first beacon that matches (i.e., one of your three), it’ll report an “enter” event with that one.

If you want to make sure you get the majors/minors of all three beacons, either (a) monitor for each of them separately (i.e., 3 regions, defined by UUID+major+minor of each beacon—but then you already need to know the majors/minors upfront, so I guess need to scan for them :smile:), or (b) use ranging instead.

Thank you for your reply.

I’ve done as you told me but the main problem still occur. The beacons are not directly discovered or not at all!
I tried to copy the same code as in the Proximity Content for Multiple Beacons template in cloud but it is not even getting called…

proximityContentManager.setListener(new ProximityContentManager.Listener() {
            @Override
            public void onContentChanged(Object content) {
                String text;
                Integer backgroundColor;
                if (content != null) {
                    EstimoteCloudBeaconDetails beaconDetails = (EstimoteCloudBeaconDetails) content;
                    text = "You're in " + beaconDetails.getBeaconName() + "'s range!";
                    backgroundColor = BACKGROUND_COLORS.get(beaconDetails.getBeaconColor());
                    myMethod(beaconDetails);
                   
                } else {
                    text = "No beacons in range.";
                    backgroundColor = null;
                }

Can you share your code after modifications? Are all your beacons discoverable by the Estimote app?

private void initRegions() {
        mRegionBlueberry = new Region("BlueberryRegion", UUID.fromString("B9407F30-F5F8-466E-AFF9-25556B57FE6D"), 3000, 7000);
        mRegionIcyMarshmallow = new Region("IcyMarshmallowRegion", UUID.fromString("B9407F30-F5F8-466E-AFF9-25556B57FE6D"), 2000, 6000);
        mRegionMint = new Region("MintRegion", UUID.fromString("B9407F30-F5F8-466E-AFF9-25556B57FE6D"), 1000, 5000);
    }

    private void initBeacons() {
        mBeaconManagerBlueberry = new BeaconManager(getApplicationContext());
        mBeaconManagerIcyMarshmallow = new BeaconManager(getApplicationContext());
        mBeaconManagerMint = new BeaconManager(getApplicationContext());
    }

    private void connectBeacons() {
        mBeaconManagerMint.connect(new BeaconManager.ServiceReadyCallback() {
            @Override
            public void onServiceReady() {
                mBeaconManagerMint.startMonitoring(mRegionMint);
            }
        });
        mBeaconManagerBlueberry.connect(new BeaconManager.ServiceReadyCallback() {
            @Override
            public void onServiceReady() {
                mBeaconManagerBlueberry.startMonitoring(mRegionBlueberry);
            }
        });
        mBeaconManagerIcyMarshmallow.connect(new BeaconManager.ServiceReadyCallback() {
            @Override
            public void onServiceReady() {
                mBeaconManagerIcyMarshmallow.startMonitoring(mRegionIcyMarshmallow);
            }
        });
    }

    private BeaconManager mBeaconManagerBlueberry;
    private BeaconManager mBeaconManagerIcyMarshmallow;
    private BeaconManager mBeaconManagerMint;

    private Region mRegionBlueberry;
    private Region mRegionIcyMarshmallow;
    private Region mRegionMint;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_test);
        grabAttributes();

        setSupportActionBar(mToolbar);
        setPagerAndAdapter();

        manageFAB();

        initBeacons();
        initRegions();
        connectBeacons();
        setMonitoringListeners();

    }

    private void setMonitoringListeners() {
        mBeaconManagerIcyMarshmallow.setMonitoringListener(new BeaconManager.MonitoringListener() {
            @Override
            public void onEnteredRegion(Region region, List<Beacon> list) {
                App.showSnackBar("Beacon: " + list.get(0).getMajor() + " : " + list.get(0).getMinor(), COORDINATOR_LAYOUT);
            }

            @Override
            public void onExitedRegion(Region region) {
                App.showSnackBar("Out of Region: " + region.getMajor() + " : " + region.getMinor(), COORDINATOR_LAYOUT);
            }
        });
        mBeaconManagerBlueberry.setMonitoringListener(new BeaconManager.MonitoringListener() {
            @Override
            public void onEnteredRegion(Region region, List<Beacon> list) {
                App.showSnackBar("Beacon: " + list.get(0).getMajor() + " : " + list.get(0).getMinor(), COORDINATOR_LAYOUT);
            }

            @Override
            public void onExitedRegion(Region region) {
                App.showSnackBar("Out of Region: " + region.getMajor() + " : " + region.getMinor(), COORDINATOR_LAYOUT);
            }
        });
        mBeaconManagerMint.setMonitoringListener(new BeaconManager.MonitoringListener() {
            @Override
            public void onEnteredRegion(Region region, List<Beacon> list) {
                App.showSnackBar("Beacon: " + list.get(0).getMajor() + " : " + list.get(0).getMinor(), COORDINATOR_LAYOUT);
            }

            @Override
            public void onExitedRegion(Region region) {
                App.showSnackBar("Out of Region: " + region.getMajor() + " : " + region.getMinor(), COORDINATOR_LAYOUT);
            }
        });
    }


    private void grabAttributes() {
        COORDINATOR_LAYOUT = (CoordinatorLayout) findViewById(R.id.coordinator_layout_all);

        mFab = (FloatingActionButton) findViewById(R.id.fab);

        mToolbar = (Toolbar) findViewById(R.id.app_bar);
        mPager = (ViewPager) findViewById(R.id.pager);
        mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
    }

Ah, I see! You only need a single Beacon Manager, and three regions, one for each beacon. Something like that:

mBeaconManager.connect(new BeaconManager.ServiceReadyCallback() {
    @Override
    public void onServiceReady() {
        mBeaconManager.startMonitoring(mRegionBlueberry);
        mBeaconManager.startMonitoring(mRegionIcyMarshmallow);
        mBeaconManager.startMonitoring(mRegionMint);
    }
});

// ...

mBeaconManager.setMonitoringListener(new BeaconManager.MonitoringListener() {
    @Override
    public void onEnteredRegion(Region region, List<Beacon> list) {
        if (region.getIdentifier().equals(mRegionMint.getIdentifier()) {
            // mint handler
        } else if // ... etc.
    }

    // similar logic in onExitedRegion
});

Sorry, I wasn’t descriptive enough in my previous post!

1 Like

Still the same problem, not triggering quickly :(. I moved to ranging instead.

Responsiveness is another topic. Ranging is more responsive, as it keeps scanning for beacons all the time. Monitoring is meant to be energy-efficient (to conserve the smartphone’s battery), so that it’s okay to use even if the app is in the background. But that comes at the expense of responsiveness.

1 Like

I tried this but still its detecting only one beacon