Xamarin Forms 使用 CrossGeolocator 获取前台服务位置更新
Posted
技术标签:
【中文标题】Xamarin Forms 使用 CrossGeolocator 获取前台服务位置更新【英文标题】:Xamarin Forms Getting foreground service location updates with CrossGeolocator 【发布时间】:2021-10-10 22:52:01 【问题描述】:我正在使用 CrossGeolocator 插件在 android 的 Xamarin Forms 应用程序中订阅位置更新(对于 ios,即使应用程序在后台,位置更新也会继续)。
我实现了一个前台服务,这样即使应用程序进入后台,我也可以继续获取位置。
据我了解,如果我在前台服务中收听位置更新,我应该能够获得位置更新。
但是,当应用程序进入后台时,我没有获得位置更新。
我的服务数据源的 StartCommand:
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
Notification notif = DependencyService.Get<INotification>().ReturnNotif();
StartForeground(ServiceRunningNotifID, notif);
CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(10), 0, true, new Plugin.Geolocator.Abstractions.ListenerSettings
ActivityType = ActivityType.Other,
PauseLocationUpdatesAutomatically = false,
AllowBackgroundUpdates = true,
DeferLocationUpdates = false,
ListenForSignificantChanges = false,
);
CrossGeolocator.Current.PositionChanged += PositionChanged;
CrossGeolocator.Current.PositionError += PositionError;
return StartCommandResult.Sticky;
还有事件:
private void PositionError(object sender, PositionErrorEventArgs e)
Console.WriteLine($"e.Error");
private void PositionChanged(object sender, PositionEventArgs e)
Console.WriteLine($"e.Position.Latitude, e.Position.Longitude");
这些事件仅在应用处于活动状态时触发。服务启动,设备显示服务正在运行的通知标志。
我已分配所需的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.LOCATION_HARDWARE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
任何人都可以对实现有所了解吗? 如果需要,我可以提供额外的代码。
【问题讨论】:
【参考方案1】:我通过添加以下内容找到了解决方案:
ForegroundServiceType = ForegroundService.TypeDataSync | ForegroundService.TypeLocation
作为前台服务中的服务属性
[Service(ForegroundServiceType = ForegroundService.TypeDataSync | ForegroundService.TypeLocation)]
public class LocationForegroundService : Service
...
【讨论】:
【参考方案2】:每个平台的后台更新处理方式略有不同。对于 Android,您需要集成一个订阅位置更改和用户界面绑定的前台服务。
您可以为此使用 Xamarin.Essentials 和 MessagingCenter。
[Service]
public class AndroidLocationService : Service
CancellationTokenSource _cts;
public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
public override IBinder OnBind(Intent intent)
return null;
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
_cts = new CancellationTokenSource();
Notification notif = DependencyService.Get<INotification>().ReturnNotif();
StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notif);
Task.Run(() =>
try
var locShared = new Location();
locShared.Run(_cts.Token).Wait();
catch (OperationCanceledException)
finally
if (_cts.IsCancellationRequested)
var message = new StopServiceMessage();
Device.BeginInvokeOnMainThread(
() => MessagingCenter.Send(message, "ServiceStopped")
);
, _cts.Token);
return StartCommandResult.Sticky;
public override void OnDestroy()
if (_cts != null)
_cts.Token.ThrowIfCancellationRequested();
_cts.Cancel();
base.OnDestroy();
有关详细信息,请查看以下链接中的代码示例。 https://***.com/a/63665571/11850033
【讨论】:
以上是关于Xamarin Forms 使用 CrossGeolocator 获取前台服务位置更新的主要内容,如果未能解决你的问题,请参考以下文章
在 Xamarin.Forms 中使用 Android 绑定
Xamarin.Forms:Forms.Context 已过时