[预期行为:专门针对 iOS 15。iOS 14 或更低版本可以正常工作]
我有一个 Xamarin.Forms iOS 应用程序,我在其中监视和测距 BLE 信标。目标是处于前台、后台或终止状态时,当我进入一个区域时,应调用 EnteredRegion() 方法,并且 DidRangeBeacons() 应该开始被触发,每秒触发一次,并且永远不会停止。当我离开区域时,应该调用 ExitRegion() 并且 DidRangeBeacons 应该停止被解雇。如果我关闭应用程序/终止应用程序,走出该区域并再次走进去,应用程序应该调用 EnteredRegion 方法并且 DidRangeBeacons() 应该开始被调用,并且只要手机在范围内,这个方法 (DidRangeBeacons) 就永远不会停止的信标。
[当前功能:始终提供位置许可]
目前,当应用程序完全关闭/杀死并且我走进该区域时, EnteredRegion 方法将执行并且 DidRange 开始被调用。它执行几秒钟并在显示关闭时停止。当显示屏再次打开时,它再次开始调用。有时,它会执行一两分钟然后再次停止。只有当显示器打开时它才会重新开始。
如果我再次解锁屏幕并浏览手机,DidRangeBeacons 将停止执行。如果再次锁定手机并打开显示屏,DidRangeBeacons 将再次开始执行。
[代码]
public class AppDelegate : UIResponder, IUIApplicationDelegate
{
[Export("window")]
public UIWindow Window { get; set; }
[Export("application:didFinishLaunchingWithOptions:")]
public bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// Override point for customization after application launch.
// If not required for your application you can safely delete this method
var bt = new BTManager();
return true;
}
// UISceneSession Lifecycle
[Export("application:configurationForConnectingSceneSession:options:")]
public UISceneConfiguration GetConfiguration(UIApplication application, UISceneSession connectingSceneSession, UISceneConnectionOptions options)
{
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration.Create("Default Configuration", connectingSceneSession.Role);
}
[Export("application:didDiscardSceneSessions:")]
public void DidDiscardSceneSessions(UIApplication application, NSSet<UISceneSession> sceneSessions)
{
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after `FinishedLaunching`.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
public class BTManager : CLLocationManagerDelegate
{
UNUserNotificationCenter center = UNUserNotificationCenter.Current;
UNMutableNotificationContent content = new UNMutableNotificationContent();
AppleLocalNotificationManager notifcationmanager = new AppleLocalNotificationManager();
CLLocationManager locationmanager;
CLBeaconRegion region;
public BTManager()
{
UNUserNotificationCenter.Current.RequestAuthorization(
UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound,
(approved, error) => { }
);
UNUserNotificationCenter.Current.Delegate = new AppleLocalNotificationManager();
locationmanager = new CLLocationManager();
locationmanager.Delegate = this;
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 override void DidChangeAuthorization(CLLocationManager manager)
{
if (manager.AuthorizationStatus == CLAuthorizationStatus.AuthorizedAlways ||
manager.AuthorizationStatus == CLAuthorizationStatus.AuthorizedWhenInUse ||
manager.AuthorizationStatus == CLAuthorizationStatus.Authorized)
{
locationmanager.StartMonitoring(region);
locationmanager.StartRangingBeacons(region);
notifcationmanager.Send("Started monitoring from auth changed", "...", "0021");
}
}
public override void DidDetermineState(CLLocationManager manager, CLRegionState state, CLRegion region)
{
if (state == CLRegionState.Inside)
{
var reg = region as CLBeaconRegion;
notifcationmanager.Send("Inside State: ", reg.Uuid.ToString(), "1121");
}
else if (state == CLRegionState.Outside)
{
var reg = region as CLBeaconRegion;
notifcationmanager.Send("Outside state: ", reg.Uuid.ToString(), "1151");
}
else
{
notifcationmanager.Send("Unknown state", "...", "131");
}
}
public override void RegionEntered(CLLocationManager manager, CLRegion region)
{
var reg = region as CLBeaconRegion;
if (reg != null)
{
notifcationmanager.Send("Entered Region", "...", "111");
}
}
public override void RegionLeft(CLLocationManager manager, CLRegion region)
{
var reg = region as CLBeaconRegion;
if (reg != null)
{
notifcationmanager.Send("Left Region", "...", "111");
}
}
public override void DidRangeBeacons(CLLocationManager manager, CLBeacon[] beacons, CLBeaconRegion region)
{
notifcationmanager.Send("Ranged Beacons", "...", "121");
}
}
public class AppleLocalNotificationManager : UNUserNotificationCenterDelegate
{
public void Send(string title,string message,string id)
{
var content = new UNMutableNotificationContent
{
Title = title,
Body = message,
Sound = UNNotificationSound.Default,
};
UNNotificationRequest request = UNNotificationRequest.FromIdentifier(
id,
content,
trigger: null
);
UNUserNotificationCenter.Current.AddNotificationRequest(
request,
error =>
{
}
);
}
public override void WillPresentNotification(
UNUserNotificationCenter center,
UNNotification notification,
Action<UNNotificationPresentationOptions> completionHandler
)
{
completionHandler(UNNotificationPresentationOptions.Alert);
}
}
当用户在范围内时,我希望 DidRangeBeacons 始终在前台、后台和终止状态下执行。任何建议如何相应地解决它?