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

标签 c# android xamarin.android location foreground-service

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

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

  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 标志重新创建它并永远运行。

最佳答案

实际上,前台服务会在手机开机时一直运行。但您也可以使用 PowerManager.WakeLock 来确保您的应用即使在设备处于 sleep 状态时也始终保持 Activity 状态。

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

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

  • 作业调度器
  • 报警管理器
  • 工作经理
  • 调度线程池执行器

你可以检查这个案例:Xamarin Android - Periodic task execution

关于c# - Android 前台定位服务在一段时间后停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71936428/

相关文章:

c# - rdlc报表如何横向显示数据?

C#.NET DirectShow 库 : Saving custom graph to a file

c# - 如果在运行时类型未知,您可以在 C# 中使用泛型方法吗?

android - 更改 ?selectableItemBackgroundBorderless 波纹颜色

android - Visual Studio 2015 Xamarin aapt.exe报错包资源不存在

c# - 是否可以使用 linq-to-sql 插入大量数据?

android - Realm 数据库是否可移植

android - Android 的说明布局

c# - Xamarin Android 构建始终失败 ("java.exe"退出并显示代码 2)

google-maps - 如何覆盖 Xamarin Android Manifest 中的键