我在Xamarin.iOS
中实现了一个信标检测器应用程序,该应用程序使用以下类来检测 iBeacons 。
递归调用方法StartScanning
和GetAvailableBeacons()
以获取检测到的信标。但是,在很短的时间内,电池耗电量太大。如何在每60秒后定期进行扫描?经过一番研究,我发现我们可以停止测距。有人可以建议我应该在下面的代码中停止范围吗?
下面是执行iBeacons检测的实现逻辑。
private CLLocationManager _locationManager;
private CLBeaconRegion _rBeaconRegion;
private CLBeaconRegion _eBeaconRegion;
readonly ObservableCollection<DetectedBeacon> _foundBeacons;
private ObservableCollection<string> _editableBeaconsList;
private bool _firstInitialization;
public BeaconDetector()
{
_foundBeacons = new ObservableCollection<DetectedBeacon> ();
Timer(); // see the implementation below
_firstInitialization = true;
}
private void SetupBeaconRanging(string uuid)
{
_locationManager = new CLLocationManager();
_locationManager.AuthorizationChanged += LocationManagerAuthorizationChanged;
var rUuid = new NSUuid(uuid);
_rBeaconRegion = new CLBeaconRegion(rUuid, uuid);
var eUuid = new NSUuid(uuid);
_eBeaconRegion = new CLBeaconRegion(eUuid, uuid);
_rBeaconRegion.NotifyEntryStateOnDisplay = true;
_rBeaconRegion.NotifyOnEntry = true;
_rBeaconRegion.NotifyOnExit = true;
_eBeaconRegion.NotifyEntryStateOnDisplay = true;
_eBeaconRegion.NotifyOnEntry = true;
_eBeaconRegion.NotifyOnExit = true;
_locationManager.DidRangeBeacons += HandleDidRangeBeacons;
_locationManager.RequestAlwaysAuthorization();
}
private void LocationManagerAuthorizationChanged(object sender, CLAuthorizationChangedEventArgs e)
{
if (e.Status == CLAuthorizationStatus.AuthorizedAlways)
{
_locationManager.StartRangingBeacons(_rBeaconRegion);
}
}
private void HandleDidRangeBeacons(object sender, CLRegionBeaconsRangedEventArgs e)
{
if (e.Beacons.Length > 0) // beacons length > 0
{
foreach (var b in e.Beacons)
{
if (_foundBeacons != null && _foundTrackers.Count > 0)
{
_foundBeacons?.Add(new DetectedBeacon
(b.ProximityUuid.ToString(), "", b.Major.ToString(), b.Minor.ToString(), string.Concat(b.Major, b.Minor),null));
}
}
}
public void Timer()
{
Device.StartTimer(TimeSpan.FromSeconds(20),
() =>
{
SetNewRegion(_rBeaconRegion);
return true;
});
}
public void DiscardRegion()
{
_locationManager.StopRangingBeacons(_eBeaconRegion);
}
public void SetNewRegion(CLBeaconRegion region)
{
_locationManager.RequestState(region);
_locationManager.StartMonitoring(region);
_locationManager.StartRangingBeacons(region);
}
public ObservableCollection<DetectedBeacon> GetAvailableBeacons()
{
return !_paused ? _foundBeacons : null;
}
public void StartScanning(ObservableCollection<string> beaconList)
{
CreatePreDefinedList(beaconList);
_foundBeacons.Clear();
DetectRegion();
}
}