Search code examples
androideclipseibeaconibeacon-android

Kontakt.io iBeacon gets scanned with too much interval on Android


I bought 3 kontakt.io iBeacon and I had no problem to create the code in order to scan them on IOS but for android I'm having some problems.. The error is that I can correctly scan the iBeacons once but after that they doesn't gets scanned anymore or they gets scanned after a long period of time, this is the code I've used so far:

public class BeaconMonitorActivity extends Activity {

    private static final int REQUEST_CODE_ENABLE_BLUETOOTH = 1;

    private BeaconManager beaconManager;

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

        beaconManager = BeaconManager.newInstance(this);
        beaconManager.setMonitorPeriod(MonitorPeriod.MINIMAL);
        beaconManager.setScanMode(1);
        beaconManager.setForceScanConfiguration(ForceScanConfiguration.DEFAULT);
        beaconManager.registerMonitoringListener(new BeaconManager.MonitoringListener() {
            @Override
            public void onMonitorStart() {

            }

            @Override
            public void onMonitorStop() {}

            @Override
            public void onBeaconsUpdated(final Region region, final List<BeaconDevice> beacons) {}

            @Override
            public void onBeaconAppeared(final Region region, final BeaconDevice beacon) {

                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(
                    new Runnable()
                    {
                        @Override
                        public void run()
                        {
                            if(beacon.getProximity() == Proximity.IMMEDIATE)
                            {
                                if(beacon.getMinor() == 33506)
                                {
                                    AlertDialog.Builder builder = new AlertDialog.Builder(BeaconMonitorActivity.this);
                                    builder.setMessage("Trovato iBeacon 1")
                                       .setCancelable(false)
                                       .setPositiveButton("Dettagli", new DialogInterface.OnClickListener() {
                                           public void onClick(DialogInterface dialog, int id) {
                                                BeaconMonitorActivity.this.finish();
                                           }
                                       })
                                       .setNegativeButton("Continua lo Scan", new DialogInterface.OnClickListener() {
                                           public void onClick(DialogInterface dialog, int id) {
                                               try {
                                                beaconManager.startMonitoring();
                                            } catch (RemoteException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                            }
                                               try {
                                                    beaconManager.startMonitoring();
                                                } catch (RemoteException e) {
                                                    // TODO Auto-generated catch block
                                                    e.printStackTrace();
                                                }
                                                dialog.cancel();
                                           }
                                       });
                                    AlertDialog alert = builder.create();
                                    alert.show();
                                }

                                if(beacon.getMinor() == 16706)
                                {
                                    AlertDialog.Builder builder = new AlertDialog.Builder(BeaconMonitorActivity.this);
                                    builder.setMessage("Trovato iBeacon 2")
                                       .setCancelable(false)
                                       .setPositiveButton("Dettagli", new DialogInterface.OnClickListener() {
                                           public void onClick(DialogInterface dialog, int id) {
                                                BeaconMonitorActivity.this.finish();
                                           }
                                       })
                                       .setNegativeButton("Continua lo Scan", new DialogInterface.OnClickListener() {
                                           public void onClick(DialogInterface dialog, int id) {
                                               try {
                                                beaconManager.startMonitoring();
                                            } catch (RemoteException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                            }
                                               try {
                                                    beaconManager.startMonitoring();
                                                } catch (RemoteException e) {
                                                    // TODO Auto-generated catch block
                                                    e.printStackTrace();
                                                }
                                                dialog.cancel();
                                           }
                                       });
                                    AlertDialog alert = builder.create();
                                    alert.show();
                                }

                                if(beacon.getMinor() == 48997)
                                {
                                    AlertDialog.Builder builder = new AlertDialog.Builder(BeaconMonitorActivity.this);
                                    builder.setMessage("Trovato iBeacon 3")
                                       .setCancelable(false)
                                       .setPositiveButton("Dettagli", new DialogInterface.OnClickListener() {
                                           public void onClick(DialogInterface dialog, int id) {
                                                BeaconMonitorActivity.this.finish();
                                           }
                                       })
                                       .setNegativeButton("Continua lo Scan", new DialogInterface.OnClickListener() {
                                           public void onClick(DialogInterface dialog, int id) {
                                               try {
                                                beaconManager.startMonitoring();
                                            } catch (RemoteException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                            }
                                               try {
                                                beaconManager.startMonitoring();
                                            } catch (RemoteException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                            }
                                                dialog.cancel();
                                           }
                                       });
                                    AlertDialog alert = builder.create();
                                    alert.show();
                                }
                            }
                        }
                    }
                );

            }

            @Override
            public void onRegionEntered(final Region region) {}

            @Override
            public void onRegionAbandoned(final Region region) {}


        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        if(!beaconManager.isBluetoothEnabled()) {
            final Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, REQUEST_CODE_ENABLE_BLUETOOTH);
        } else if(beaconManager.isConnected()) {
            try {
                beaconManager.startRanging();
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        } else {
            connect();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        beaconManager.stopMonitoring();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        beaconManager.disconnect();
        beaconManager = null;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if(requestCode == REQUEST_CODE_ENABLE_BLUETOOTH) {
            if(resultCode == Activity.RESULT_OK) {
                connect();
            } else {
                Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_LONG).show();
                getActionBar().setSubtitle("Bluetooth not enabled");
            }
            return;
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    private void connect() {
        try {
            beaconManager.connect(new OnServiceBoundListener() {
                @Override
                public void onServiceBound() {
                    try {
                        beaconManager.startMonitoring();
                        //beaconManager.startMonitoring(Region.EVERYWHERE);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
        } catch (RemoteException e) {
            throw new IllegalStateException(e);
        }
    }
}

Am I scanning for the beacons in the wrong function? Please help


Solution

    1. In onStart() you invoke BeaconManager.startRanging(). On the contrary, in onStop() you invoke BeaconManager.stopMonitoring().

    Well, this does not work that way. You can either range or monitor. You cannot perform both scans simultaneously. Mixing ranging and monitoring results in exception being raised.

    While ranging you are focused on physical distance from remote devices that interest you.

    Whereas, if you monitor them, you want to be rather notified of whether they are nearby or not. In other words, whether you are in specific region or not.

    1. I see that you want to execute code once you find the beacon with specific minor value from IMMEDIATE distance. While what you wrote should work it is not preferrable way to solve it. You can enable filtering for specific values like minor via Filters.newMajorFilter(), or via Filters.CustomFilter

    Have you seen the kontakt-beacon-sample-admin-app ? This project demonstrates different approaches of kontakt.io's Android SDK usage.