Xamarin Android,我需要在关闭应用程序时取消前台服务和通知

时间:2019-06-18 01:24:00

标签: android xamarin xamarin.android

让我解释一下情况。
我需要每10分钟安排一次任务。
即使该应用程序在后台并且即使省电也已启动,此任务仍需要网络和磁盘资源。
我尝试了AlarmManager,JobScheduler和ForegroundService。
然后,只有省电模式启动时才起作用的一个是ForegroundService。

在xamarin中,我已经在MainActivity.cs中启动了前景服务,如下所示。

void StartSomeService()
{
    var intent = new Intent(this, typeof(SomeService));
    StartForegroundService(intent);
}

在“前景”服务中,我有一个显示在android中的通知。
当用户从屏幕上滑动应用程序或单击“ X”关闭应用程序时,我需要终止前台服务。

本节确实取消/关闭了通知,但是我再次调用StartService只是为了终止服务,因此感觉不对。

TestService

public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
    if ("stop_service" == intent.Action)
    {
        StopForeground(true);
        StopSelf();
    }
    else
    {
        _cts = new CancellationTokenSource();

        RegisterForegroundService();

        Task.Factory.StartNew(async () =>
        {
            while (true)
            {                        
                await Task.Delay(TimeSpan.FromSeconds(30));

                // DO SOME WORK
            }
        });
    }

    return StartCommandResult.Sticky;
}

MainActivity

protected override void OnDestroy()
{
    var intent = new Intent(this, typeof(TestService));
    intent.SetAction("stop_service");
    StartService(intent);

    base.OnDestroy();
}

2 个答案:

答案 0 :(得分:1)

要停止前台服务,我通常使用:

var intent = new Intent(this, typeof(ForegroundService));
StopService(intent);

这将依次在前台服务内部触发OnDestroy()

然后在OnDestroy()中,我这样做:

if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
{
    StopForeground(StopForegroundFlags.Remove);
}
else
{
    StopForeground(true);
}

StopSelf();

否则,我看到服务再次启动而又没有停止的奇怪现象。

答案 1 :(得分:1)

我最近遇到了一个相同的问题,即如果用户滑动应用程序将其关闭,则需要我的前台服务结束。

对我有用的是重写OnTaskRemoved,当用户删除服务操作中涉及的任务时调​​用该方法。您可以将Cheesebaron的代码放入此方法中,它应停止前台服务。我还添加了一行代码来终止该应用程序,否则该应用程序似乎仍在后台运行:

public override void OnTaskRemoved(Intent rootIntent)
        {
            if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
            {
                StopForeground(StopForegroundFlags.Remove);
            }
            else
            {
                StopForeground(true);
            }

            StopSelf();

            base.OnDestroy();
            System.Diagnostics.Process.GetCurrentProcess().Kill();

        }