Search code examples
altbeacon

How to restart the scan in Altbeacon library?


I have referred to this question already : Stopping and restarting foreground service scanning with altbeacon

My requirement is to restart the beacon scan depending on API response containing scanTime and waitTime. I would have started a scan with default config and once i receive API response from server i need to restart the scan with new config. So this is the code i have. Is this valid to just stop and then start the scan again? Will this have any adverse effect?

public void reconnect(int scanTimeInMills, int waitTimeInMillis) {
try {
    if (beaconManager != null) {
        beaconManager.stopRangingBeaconsInRegion(ALL_REGION);
        beaconManager.unbind(this);
    }
    beaconManager = null;
    beaconManager = BeaconManager.getInstanceForApplication(MyApplication.getInstance());
    beaconManager.getBeaconParsers().add(new BeaconParser()
            .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

    beaconManager.setForegroundScanPeriod(scanTimeInMills);
    beaconManager.setBackgroundScanPeriod(scanTimeInMills);
    beaconManager.setBackgroundBetweenScanPeriod(waitTimeInMillis);
    beaconManager.setForegroundBetweenScanPeriod(waitTimeInMillis);

    if (!beaconManager.isBound(this)) {

        String channelName = "App Notification Service";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel chan = new NotificationChannel(
                    String.valueOf(Constant.APP_CLOCKIN_NOTIIFICATION_ID), channelName,
                    NotificationManager.IMPORTANCE_DEFAULT);
            chan.setLightColor(Color.BLUE);
            chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
            NotificationManager manager = (NotificationManager) WrkspotApplication.getInstance()
                    .getSystemService(Context.NOTIFICATION_SERVICE);
            assert manager != null;
            manager.createNotificationChannel(chan);
        }
        Intent intent = new Intent(MyApplication.getInstance(), HomeScreenActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                MyApplication.getInstance(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
        );
        NotificationCompat.Builder notificationBuilder = new Builder(
                MyApplication.getInstance())
                .setLargeIcon(BitmapFactory
                        .decodeResource(MyApplication.getInstance().getResources(),
                                R.mipmap.ic_launcher))
                .setSmallIcon(R.drawable.ic_logo_notification)
                .setContentTitle(getApplicationContext().getString(R.string.app_name))
                .setContentText(
                        getApplicationContext().getString(R.string.you_are_clocked_in))
                .setStyle(new BigTextStyle().bigText(
                        getApplicationContext().getString(R.string.you_are_clocked_in)))
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                .setChannelId(String.valueOf(Constant.APP_CLOCKIN_NOTIIFICATION_ID));
        beaconManager.enableForegroundServiceScanning(notificationBuilder.build(),
                Constant.APP_CLOCKIN_NOTIIFICATION_ID);
        beaconManager.bind(this);
    }
} catch (Exception e) {
    Log.e(getClass().getSimpleName(), String.valueOf(e.getMessage()));
}

}


Solution

  • This really does not require all that code. Just use:

    beaconManager.setForegroundScanPeriod(scanTimeInMills);
    beaconManager.setForegroundBetweenScanPeriod(waitTimeInMillis);
    beaconManager.setBackgroundMode(false);
    beaconManager.updateScanPeriods();
    

    You do not need to set both foreground and background scan periods. Just do not use BackgroundPowerSaver, and you can leave it in foreground mode all the time.

    All the complex logic binding and unbinding shown in the question can cause trouble because it starts and stops the scanning process. This is an asynchronous operation, and it can lead to race conditions. Best to keep it simple.