You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin中按钮点击后Beacon监听器持续运行问题咨询

关于BeaconDetector中监听器持续运行与定时检测的问题

先直接解答你的第一个疑问:点击按钮后,_rangeNotifier.DidRangeBeaconsInRegionComplete不会持续运行。原因是你每次调用DetectAvailableBeacons()都会重新创建全新的_rangeNotifier和_monitorNotifier实例,而且默认情况下,BeaconManager绑定完成后只会执行一次扫描流程,扫描结束后就会停止,不会主动重复触发测距逻辑。

下面给你两种可行的方案,实现每30秒自动检测一次的需求:


方案1:自定义定时器重复触发检测

你可以在Droid端的BeaconDetector类中添加一个定时器,在首次启动检测后,每隔30秒重新执行扫描逻辑。同时要注意处理好定时器的生命周期,避免内存泄漏。

修改后的BeaconDetector.cs示例代码:

private System.Timers.Timer _detectionTimer;
private bool _isDetecting; // 标记是否正在检测,防止重复触发

public void DetectAvailableBeacons()
{
    if (_isDetecting) return;
    
    _monitorNotifier = new MonitorNotifier();
    _rangeNotifier = new RangeNotifier();
    _tagRegion = new Region("NewRegion", null, null, null);
    
    _rangeNotifier.DidRangeBeaconsInRegionComplete += RangingBeaconsInRegionComplete;
    
    // 初始化定时器,间隔30秒
    _detectionTimer = new System.Timers.Timer(30000);
    _detectionTimer.Elapsed += (sender, e) => RunBeaconScan();
    _detectionTimer.AutoReset = true; // 设置自动重复触发
    
    // 首次检测立即执行
    RunBeaconScan();
    _isDetecting = true;
}

private void RunBeaconScan()
{
    // 确保在UI线程操作(如果需要更新UI的话)
    Activity.RunOnUiThread(() =>
    {
        // 先解绑再重新绑定,触发新一轮扫描
        _beaconManager.Unbind(this);
        _beaconManager.Bind(this);
    });
}

// 提供停止检测的方法,在页面销毁或不需要时调用
public void StopBeaconDetection()
{
    _isDetecting = false;
    _detectionTimer?.Stop();
    _detectionTimer?.Dispose();
    _beaconManager.Unbind(this);
}

对应的按钮点击事件可以优化为支持启停切换:

private IBeaconLocator _beaconDetection;

public void Button_Clicked(object sender, EventArgs e)
{
    _beaconDetection = DependencyService.Get<IBeaconLocator>();
    if (_beaconDetection is BeaconDetector detector)
    {
        if (!detector.IsDetecting)
        {
            detector.DetectAvailableBeacons();
        }
        else
        {
            detector.StopBeaconDetection();
        }
    }
}

方案2:利用BeaconManager内置扫描周期配置

Android Beacon Library本身支持配置扫描的周期和间隔,你可以直接通过库的API设置,让它自动重复扫描,不需要自己维护定时器,更符合库的设计逻辑。

修改后的DetectAvailableBeacons()方法示例:

public void DetectAvailableBeacons()
{
    _beaconManager = BeaconManager.GetInstanceForApplication(Application.Context);
    
    // 配置扫描参数:扫描持续1秒,两次扫描间隔29秒,总周期30秒
    _beaconManager.SetForegroundScanPeriod(1000);       // 单次扫描持续时长(毫秒)
    _beaconManager.SetForegroundBetweenScanPeriod(29000); // 扫描间隔时长(毫秒)
    
    _monitorNotifier = new MonitorNotifier();
    _rangeNotifier = new RangeNotifier();
    _tagRegion = new Region("NewRegion", null, null, null);
    
    _rangeNotifier.DidRangeBeaconsInRegionComplete += RangingBeaconsInRegionComplete;
    
    _beaconManager.Bind(this);
}

这种方式下,BeaconManager会按照你设置的周期自动重复执行扫描,DidRangeBeaconsInRegionComplete会在每次扫描完成后触发。如果需要后台也保持扫描,还需要额外配置后台扫描参数和申请对应权限(Android 10+需要ACCESS_BACKGROUND_LOCATION权限)。


额外注意事项

  • 无论用哪种方案,都要记得在页面销毁或不再需要检测时,调用_beaconManager.Unbind(this)解除绑定,释放资源,避免内存泄漏。
  • 如果需要在后台长期运行,要注意Android系统的后台限制,可能需要优化电池使用策略或者申请特殊权限。
  • 在RangingBeaconsInRegionComplete方法中处理扫描结果时,要注意线程安全,更新UI的操作必须切换到UI线程执行。

内容的提问来源于stack exchange,提问作者ExpertGenie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:25:38