Xamarin.Android: Служба останавливается, когда экран выключен (режим ожидания Doze / App)

Я должен внедрить услугу, где я передаю GPS (широта / долгота) каждые 120 секунд. на мой бэкэнд REST.

У меня проблема в том, что служба перестает работать при выключенном экране.

  1. Попытка с помощью StartedService и BroadcastReceiver
  2. Попытка с помощью IntentService и WakefulBroadcastReceiver

1. Попытка работает, например, на SAMSUNG Galaxy X COVER, но не на HUAWEI P9 Lite. Несмотря на то, что я отключил режим энергосбережения (Power Apps) в телефоне HUAWEI. Так что мое приложение продолжает работать, когда экран выключен. Примерно через 10 минут я включил экран на телефоне HUAWEI и увидел в запущенных службах, что служба запущена (истекшие секунды), чтобы я мог убедиться, что служба не закрыта.

2. Попытка работает на телефоне, когда экран выключен.

Обе попытки работают правильно, когда экран включен (без сна).

Примечание: для краткости я вычеркнул код не соответствующих методов (выборка / передача данных gps).

Вот код для 1. Попытка:

обслуживание

[Service]
public class GpsTrackerService : Service
{
    private static readonly string LogTag = "X:TruckerApp-" + typeof(GpsTrackerService).Name;
    private static readonly int NOTIFICATION_ID = 10000;
    private MobileServiceClient _mobileServiceClient;

    public TelephonyManager GetTelefonyManager()
    {
        return (Android.Telephony.TelephonyManager) GetSystemService(TelephonyService);
    }

    public bool IsRunningAsService { get; set; }


    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        Log.Debug(LogTag, "GpsTrackerService.OnStartCommand :: Service started. Timer instantiated.");
        GpsTrackerServiceUtils.SendGenericMessageToApplicationInsights("Gps-Info", LogTag, _mobileServiceClient, this, "GpsTrackerService.OnStartCommand :: Service started.Timer instantiated.");

        Task.Run(async () =>
        {
            try
            {
                await DoWork();
                await Task.Delay(TimeSpan.FromMinutes(2));
            }
            catch (Exception e)
            {
                Log.Debug(LogTag, $"GpsTrackerService.HandleTimerCallback :: (OUTER try-catch) Exception:{e.Message} Type:{e.GetType().Name}, Stacktrack:{e.StackTrace}");
                if (e.InnerException != null)
                {
                    Log.Debug(LogTag, $"GpsTrackerService.HandleTimerCallback :: (OUTER try-catch) Exception:{e.InnerException.Message} Type:{e.InnerException.GetType().Name}, Stacktrack:{e.InnerException.StackTrace}");
                }
                GpsTrackerServiceUtils.SendExceptionToApplicationInsights(e, LogTag, _mobileServiceClient, this);
            }
            finally
            {
                // Restart Service
                Intent broadcastIntent = new Intent(action: GpsConstants.GpsRestart);
                SendBroadcast(broadcastIntent);
            }

        });

        return StartCommandResult.Sticky;
    }

      public override IBinder OnBind(Intent intent)
    {
        // This is a started service, not a bound service, so we just return null.
        return null;
    }
}

BroadcastReceiver

[BroadcastReceiver(Enabled = true, Exported = true, Name = GpsConstants.GpsBroadcastReceiver, Label = "RestartServiceWhenStopped")]
[IntentFilter(new[] {GpsConstants.GpsRestart})]
public class GpsTrackerServiceBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        try
        {
            MetricsManagerHelper.Instance.SendGenericMessageToApplicationInsights("Gps-Info", "OnReceive :: Gps Service broadcast message received. Restarting GPS Service...");
            context.StartService(new Intent(context, typeof(GpsTrackerService)));
         }
        catch (Exception e)
        {
            MetricsManagerHelper.Instance.SendExceptionToApplicationInsights(e);
        }
    }
}

Зарегистрируйте Broadcastreceiver в MainActivity.OnCreate

 GpsTrackerServiceBroadcastReceiver = new GpsTrackerServiceBroadcastReceiver();
 RegisterReceiver(GpsTrackerServiceBroadcastReceiver, new IntentFilter(GpsConstants.GpsBroadcastReceiver));

2.Attempt

обслуживание

[Service]
public class GpsTrackerIntentService : IntentService
{
    private static readonly string LogTag = "X:TruckerApp-" + typeof(GpsTrackerIntentService).Name;
    private static readonly int NOTIFICATION_ID = 10000;
    private MobileServiceClient _mobileServiceClient;

    public TelephonyManager GetTelefonyManager()
    {
        return (TelephonyManager) GetSystemService(TelephonyService);
    }

    protected override async void OnHandleIntent(Intent intent)
    {
        try
        {
            // perform task
            await Bootstrap();

            GpsTrackerServiceUtils.SendGenericMessageToApplicationInsightsWakeLock("Gps-Info", LogTag, _mobileServiceClient, this, "GpsTrackerService.OnHandleIntent :: Invoked.");

            await DoWork();
            await Task.Delay(TimeSpan.FromMinutes(2));
        }
        catch (Exception e)
        {
            Log.Debug(LogTag, $"GpsTrackerService.OnCreate :: Exception:{e.Message} Type:{e.GetType().Name}");
            GpsTrackerServiceUtils.SendExceptionToApplicationInsightsWakeLock(e, LogTag, _mobileServiceClient, this);
        }
        finally
        {
            WakefulBroadcastReceiver.CompleteWakefulIntent(intent);
            SendBroadcast(new Intent(this, typeof(GpsTrackerServceWakefulReceiver)));
            //var wakefulReceiverIntent = new Intent(this, typeof(GpsTrackerServceWakefulReceiver));
            //var pending = PendingIntent.GetBroadcast(this, 0, wakefulReceiverIntent, PendingIntentFlags.UpdateCurrent);
            //AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
            //manager.SetRepeating(AlarmType.RtcWakeup, SystemClock.ElapsedRealtime(), 120 * 1000, pending);
        }
    }


    public async Task DoWork()
    {
        // long running code ...
        Log.Debug(LogTag, "GpsTrackerService.HandleTimerCallback :: Invoked.");
        GpsTrackerServiceUtils.SendGenericMessageToApplicationInsightsWakeLock("Gps-Info", LogTag, _mobileServiceClient, this, "GpsTrackerService.HandleTimerCallback :: Invoked.");


    }
}

WakefulReceiver

[BroadcastReceiver]
public class GpsTrackerServceWakefulReceiver : WakefulBroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        var serviceIntent = new Intent(context, typeof(GpsTrackerIntentService));
        StartWakefulService(context, serviceIntent);
    }
}

AndroidManifest.xml

добавлено разрешение WAKE_LOCK

  <uses-permission android:name="android.permission.WAKE_LOCK"/>
  <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>

Теперь я действительно отчаялся. Надеюсь, кто-нибудь может мне помочь. Спасибо

Эрик

0 ответов

Другие вопросы по тегам