Повторение тревоги для управления режимом дремоты

У меня есть приложение, которое автоматизирует на основе местоположения пользователя. Сейчас я работаю с дремальным режимом, так как доза не дает возможности отправлять запросы в фоновом режиме на основании изменений местоположения. Я хочу, чтобы мой сервис подключался к Интернету каждые 9 минут или во время технического обслуживания. Я использую AlarmManager и SetExactAndAllowWhileIdle, но по какой-то причине мои сигналы снова и снова рассылаются спамом, несмотря на то, что я даю им AlarmType.RtcWakeup, который появится в будущем. Моя служба определения местоположения запускается при запуске приложения, и моя служба также запускается / перезапускается, когда приложение завершается и когда устройство перезагружается.

Я не понимаю, когда и где поставить будильник. Прямо сейчас я устанавливаю свой будильник, когда начинается служба определения местоположения. Аварийные сигналы продолжают срабатывать и даже немедленно срабатывать, а не в тот момент, когда я их включил. Я устанавливаю SetExactAndAllowWhileIdle с AlarmType.RtcWakeup, и мое время выглядит правильно. Я распечатываю это с тостами, и оно ясно показывает, что это произойдет через ~9 минут.

Когда я должен установить будильник? Разве я не должен действовать на каждом OnHandleIntent, которое я получаю от тревоги? Я неправильно установил будильник?

Прямо сейчас я звоню, когда моя служба определения местоположения запускается:

StartAlarm_Now ();

Должен ли я вместо этого установить это, когда приложение завершено или приостановлено?

    // I'm using AlarmType.RtcWakeup, so I need to get current time in milliseconds
    public static long GetDateTimesMillisecondsForToday()
    {
        var test = (DateTime.Now).Subtract(DateTime.Today);
        var hours = test.TotalHours;
        long milliseconds = (long)(test.TotalMilliseconds);
        return milliseconds;
    }

    // Calling this will set the alarm for now.  Should I ever need to do this??
    public static void StartAlarm_Now()
    {
        string id = "Now_" + new Random().Next(1000, 9999).ToString();
        StartAlarm(id, GetDateTimesMillisecondsForToday());
    }

    // Calling this will set the alarm for x seconds from now.  This is the right way to do it?  
    public static void StartAlarm_SecondsFromNow(long a_secondsFromNow)
    {
        string id = "SecondsFromNow_" + new Random().Next(1000, 9999).ToString();
        long millisecondsToUse = GetDateTimesMillisecondsForToday() + (a_secondsFromNow * 1000);
        StartAlarm(id, millisecondsToUse);
    }

    private static void StartAlarm(string id, long a_milliseconds)
    {
        TimeSpan t = TimeSpan.FromMilliseconds(a_milliseconds);
        string readableTime_fromMilliseconds = string.Format(
            "{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms",
            t.Hours,
            t.Minutes,
            t.Seconds,
            t.Milliseconds
        );
        string message = "StartAlarm " + id + " readableTime_fromMilliseconds = " + readableTime_fromMilliseconds;
        SCoreAppContext.Instance.Container.Get<ISCoreAppGlobal<Activity>>().SafeInvokeOnMainThread(() =>
        {
            Toast.MakeText(Android.App.Application.Context, message, ToastLength.Short).Show();
        });

        using (AlarmManager alarmManager = (AlarmManager)AppContext.GetSystemService(Context.AlarmService))
        {
            Intent serviceIntent = new Intent(Android.App.Application.Context, typeof(TestService));
            PendingIntent pendingIntent = PendingIntent.GetService(Android.App.Application.Context, 0, serviceIntent, PendingIntentFlags.CancelCurrent);
            alarmManager.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, a_milliseconds, pendingIntent);
        }
    }


[Service(Exported = false)]
public class TestService : IntentService
{

    public override void OnCreate()
    {
        base.OnCreate();
    }

    public override Android.OS.IBinder OnBind(Android.Content.Intent intent)
    {
        return null;
    }

    protected override async void OnHandleIntent(Intent intent)
    {
        // This part is spamming constantly while the app is running.
        // Here is where I run my code that should execute when my alarm expires, right?... That's what I'm assuming, but this is spamming a LOT.  And my alarms set for the future and this is getting called immediately
        SCoreAppContext.Instance.Container.Get<ISCoreAppGlobal<Activity>>().SafeInvokeOnMainThread(() =>
        {
            Toast.MakeText(Android.App.Application.Context, "JoeyZTestService.OnHandleIntent", ToastLength.Short).Show();
        });


        // I read that if you want the alarm to repeat, you can set another one when this one fires.  But I believe this is why mine are looping forever.  So how can i repeat if not here?  
        // The 530 is the # of seconds in the future that the alarm should fire.  
        StartAlarm_SecondsFromNow(530);
    }

}

0 ответов

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