如何在 Altbeacon 库中重新启动扫描?

How to restart the scan in Altbeacon library?

我已经提到过这个问题:Stopping and restarting foreground service scanning with altbeacon

我的要求是根据包含 scanTime 和 waitTime 的 API 响应重新启动信标扫描。我会使用默认配置开始扫描,一旦我收到来自服务器的 API 响应,我需要使用新配置重新启动扫描。所以这是我的代码。仅停止然后再次开始扫描是否有效?会不会有什么不良影响?

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()));
}

}

这真的不需要那么多代码。只需使用:

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

您不需要同时设置前台和后台扫描周期。只是不要使用BackgroundPowerSaver,你可以让它一直处于前台模式。

问题中显示的所有复杂逻辑绑定和解除绑定都会引起麻烦,因为它会启动和停止扫描过程。这是一个异步操作,它会导致竞争条件。最好保持简单。