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

iOS15下Xamarin.Forms应用DidRangeBeacons后台/被杀状态无法持续触发问题

问题核心原因

iOS 15对后台Beacon测距机制做了严格限制:默认状态下,应用被区域进入事件唤醒后,仅能获得最多10秒的后台运行时间,时间到后系统会自动挂起应用,测距回调也就停止了。再加上你现有代码存在生命周期管理漏洞,才会出现熄屏/解锁后回调停止的问题。

修复步骤

  • 第一步:修复BTManager生命周期问题
    你在AppDelegate的FinishedLaunching中将BTManager声明为局部变量,会很快被GC回收,导致Delegate回调中断,需要改为全局属性:
public class AppDelegate : UIResponder, IUIApplicationDelegate
{
    [Export("window")]
    public UIWindow Window { get; set; }
    // 改为全局属性避免被回收
    public BTManager BtInstance { get; set; }

    [Export("application:didFinishLaunchingWithOptions:")]
    public bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        BtInstance = new BTManager();
        // 新增:判断是否由位置事件唤醒应用
        if (launchOptions != null && launchOptions.ContainsKey(UIApplication.LaunchOptionsLocationKey))
        {
            BtInstance.RestartMonitoring();
        }
        return true;
    }
    // 其余原有代码保留不变
}
  • 第二步:添加必要的权限与后台模式配置
    在Info.plist中添加以下配置:

    1. 权限声明:
    • NSLocationAlwaysAndWhenInUseUsageDescription:需要始终访问位置以扫描Beacon
    • NSLocationWhenInUseUsageDescription:使用应用期间需要访问位置以扫描Beacon
    • 新增NSLocationTemporaryUsageDescriptionDictionary节点配置精确位置权限(iOS 14+强制要求)
    1. 后台模式:添加UIBackgroundModes字段,值包含location(启用后台位置更新能力)
  • 第三步:调整CLLocationManager配置
    在BTManager的构造方法中新增以下配置,提升后台存活优先级:

public BTManager()
{
    // 原有权限申请、通知配置代码保留不变
    locationmanager = new CLLocationManager();
    locationmanager.Delegate = this;
    // 新增配置
    locationmanager.AllowsBackgroundLocationUpdates = true; // 允许后台位置更新
    locationmanager.PausesLocationUpdatesAutomatically = false; // 禁止系统自动暂停位置更新
    locationmanager.ShowsBackgroundLocationIndicator = true; // iOS 14+显示后台位置使用指示器,提升后台存活优先级
    
    locationmanager.RequestAlwaysAuthorization();
    // 注意原有代码此处构造方法多了一个逗号,会编译错误,需删除
    region = new CLBeaconRegion(new NSUuid("3ABFAA22-5624-11EA-8E2D-0242AC130003"), 0, 109, "Region 1");
    region.NotifyOnEntry = true;
    region.NotifyOnExit = true;
    region.NotifyEntryStateOnDisplay = true;
}
  • 第四步:优化区域事件回调逻辑,延长后台运行时间
    当应用被杀后被区域进入事件唤醒时,原有的测距任务已停止,需要在进入区域时重新启动测距,同时申请额外的后台运行时间:
public class BTManager : CLLocationManagerDelegate
{
    // 原有属性保留不变
    private nint _bgTaskId = 0;

    // 新增重启监测的公共方法
    public void RestartMonitoring()
    {
        if (locationmanager.MonitoredRegions.Contains(region))
        {
            locationmanager.StopMonitoring(region);
            locationmanager.StopRangingBeacons(region);
        }
        locationmanager.StartMonitoring(region);
        locationmanager.StartRangingBeacons(region);
    }

    public override void RegionEntered(CLLocationManager manager, CLRegion region)
    {
        var reg = region as CLBeaconRegion;
        if (reg != null)
        {
            notifcationmanager.Send("Entered Region", "...", "111");
            // 重启测距
            locationmanager.StopRangingBeacons(reg);
            locationmanager.StartRangingBeacons(reg);
            // 申请最长30秒后台运行时间
            _bgTaskId = UIApplication.SharedApplication.BeginBackgroundTask(() =>
            {
                UIApplication.SharedApplication.EndBackgroundTask(_bgTaskId);
                _bgTaskId = 0;
            });
        }
    }

    public override void RegionLeft(CLLocationManager manager, CLRegion region)
    {
        var reg = region as CLBeaconRegion;
        if (reg != null)
        {
            notifcationmanager.Send("Left Region", "...", "111");
            // 离开区域停止测距释放资源
            locationmanager.StopRangingBeacons(reg);
            if (_bgTaskId != 0)
            {
                UIApplication.SharedApplication.EndBackgroundTask(_bgTaskId);
                _bgTaskId = 0;
            }
        }
    }
    // 其余原有回调代码保留不变
}

如果需要超过30秒的持续后台测距,iOS15+下可配合实时活动(Live Activity)或者运动传感器权限延长后台存活时间,但会相应增加电量消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:18:02