【问题标题】:Xamarin Forms Getting foreground service location updates with CrossGeolocatorXamarin Forms 使用 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" />

任何人都可以对实现有所了解吗? 如果需要,我可以提供额外的代码。

【问题讨论】:

    标签: android xamarin.forms geolocation foreground-service xamarin.essentials


    【解决方案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://stackoverflow.com/a/63665571/11850033

      【讨论】:

        猜你喜欢
        • 2015-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-12
        • 2019-10-26
        相关资源
        最近更新 更多