Android 前台定位服务在一段时间后停止

Android Foreground Location Service stops after some time

我正在使用 this 代码为我的 Xamarin Android 应用获取位置更新。我有 2 个问题。

  1. 如何让这个前台服务永远运行?我试图将 return StartCommandResult.NotSticky; 更改为 return StartCommandResult.Sticky; 并从 OnDestroy() 方法中删除任何内容,但 OS 似乎无法在服务被终止或崩溃后重新创建服务。因此,它 运行 只用了大约半天,即使我已将应用程序添加到我的电池优化排除列表中。如何让它 运行 永远?

  2. 如何正确开机启动服务? 这是我试过的。在 MainActivity.cs

    中添加了以下内容
            [IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
            public class BootReceiver : BroadcastReceiver
            {
                public Context Context { get; set; }
                public override void OnReceive(Context context, Intent intent)
                {
                    var stepServiceIntent = new Intent(context, typeof(LocationUpdatesService));
                    stepServiceIntent.PutExtra("StartedFromBoot", true);
                    if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
                    {
                        context.StartForegroundService(stepServiceIntent);
                    }
                    else
                    {
                        context.StartService(stepServiceIntent);
                    }
                }
            }

已编辑LocationUpdatesService.cs

public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            Log.Info(Tag, "Service started");
            var startedFromNotification = intent.GetBooleanExtra(ExtraStartedFromNotification, false);

            var startedFromBoot = intent.GetBooleanExtra("StartedFromBoot", false);

            if (startedFromBoot)
            {
                
                //Preferences.Set("LocationUpdates", true);
                
                StartForeground(NotificationId, StartNotification("",""));
                Preferences.Set("foreground", true);

                try
                {
                    FusedLocationClient.RequestLocationUpdates(LocationRequest, LocationCallback, Looper.MyLooper());
                }
                catch (SecurityException unlikely)
                {
                    Preferences.Set("LocationUpdates", false);
                    Log.Error(Tag, "Lost location permission. Could not request updates. " + unlikely);
                }
            }
            if (startedFromNotification)
            {
                RemoveLocationUpdates();
                StopSelf();
            }
            return StartCommandResult.Sticky;
        }

我从启动时就只获得了单个位置更新。在那次更新之后,我得到了“未知位置”,所以服务不会持续 运行。那么,如何正确地从引导启动该服务以使其持续 运行?

也许这两个问题都有一个解决方案,所以如果有一种方法可以从引导启动全功能服务,那么系统可以使用 Sticky 标志和 运行 永远重新创建它。

实际上,当phone开启时,前台服务会保持运行ning。但您也可以使用 PowerManager.WakeLock 来确保您的应用程序即使在设备处于睡眠状态时也始终保持活动状态。

你可以检查这个案例:Xamarin wakelock

另外,你好像是想循环获取用户的位置。这样就可以在前台服务运行一个定时任务了。有很多方法可以做到这一点。如:

  • JobScheduler
  • 报警管理器
  • 工作管理器
  • ScheduledThreadPoolExecutor

你可以检查这个案例: