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
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.
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.