Как я могу запускать задачу каждый день в одно и то же время в Xamarin Forms Android? - PullRequest
0 голосов
/ 17 июня 2020

Я новичок в программировании на Xamarin и Android. В настоящее время я пытаюсь создать приложение, которое проверяет положение устройства каждую ночь примерно в час ночи. Время будет установлено на странице настроек с помощью TimePicker. Единственная проблема, с которой я сейчас сталкиваюсь, - это как запланировать эту задачу, чтобы она выполнялась, даже если приложение закрыто или устройство находится в режиме ожидания. Целевая платформа - Android 9 (P ie).

До сих пор я создал службу переднего плана. Эта служба переднего плана устанавливает AlarmManager с методом SetRepeading и режимом Rtc_Wakeup. Но это не так, как я надеялся! Проблема в том, что сигнал тревоги срабатывает, когда для приложения установлено значение «Фон» или «Закрыто». Но он может срабатывать только по истечении времени срабатывания. Или я ошибаюсь?

Вы можете получить весь код из моего Git репозитория

Как лучше всего этого добиться? Спасибо! :)

Это то, что я пробовал до сих пор:)

Вот мой класс ForegroundService:


using Android.App;
using Android.Content;
using Android.OS;
using AnwesenheitsApp.Droid.Alarm;

namespace AnwesenheitsApp.Droid
{
    [Service]
    class PositionServiceDroid : Service
    {
        private Logging.Logging _logger = new Logging.Logging();
        private static AlarmHandler alarm = new AlarmHandler();

        public override StartCommandResult OnStartCommand(Intent intent,
            StartCommandFlags flags, int startId)
        {
            int messageID = 90000;

            var notifMngr = new NotificationManagerDroid();
            Notification notification = notifMngr.ReturnNotification(
                "Positions Service", "Die überwachung der Position für die" +
                " automatische Prüfung der Anwesenheit läuft!");

            StartForeground(messageID, notification);

            alarm.SetAlarm();

            return StartCommandResult.Sticky;
        }

        public override bool StopService(Intent name)
        {
            alarm.UnsetAlarm();
            return base.StopService(name);
        }

        public override void OnDestroy()
        {
            alarm.UnsetAlarm();
            base.OnDestroy();
        }

        public override IBinder OnBind(Intent intent)
        {
            return null;
        }  
    }
}

Это мой класс AlarmHandler:

using System;

using Android.App;
using Android.Content;
using Android.Runtime;

namespace AnwesenheitsApp.Droid.Alarm
{
    class AlarmHandler
    {
        public void SetAlarm()
        {
            var alarmIntent = new Intent(Application.Context, typeof(AlarmReciver));
            var pending = PendingIntent.GetBroadcast(Application.Context,
                0, alarmIntent, PendingIntentFlags.UpdateCurrent);
            var alarmManager = Application.Context.GetSystemService(Application.AlarmService)
                .JavaCast<AlarmManager>();

            //For Testing
            var now = DateTime.Now;

            var dt = new DateTime(now.Year, now.Month, now.Day,
                19, 5, 0, 0).Ticks / 10000;

            long millis = dt - now.Ticks / 10000;

            alarmManager.SetRepeating(AlarmType.RtcWakeup, millis,
                1000 * 60 * 60 * 4, pending);
        }

        public void UnsetAlarm()
        {
            var alarmIntent = new Intent(Application.Context, typeof(AlarmReciver));
            var pending = PendingIntent.GetBroadcast(Application.Context,
                0, alarmIntent, PendingIntentFlags.UpdateCurrent);
            var alarmManager = Application.Context.GetSystemService(Application.AlarmService)
                .JavaCast<AlarmManager>();

            alarmManager.Cancel(pending);
        }
    }
}

, а это класс BroadcastReceiver:

using System;
using System.Linq;
using AnwesenheitsApp.DbModels;
using Xamarin.Essentials;

using Android.Content;

namespace AnwesenheitsApp.Droid.Alarm
{
    [BroadcastReceiver]
    class AlarmReciver : BroadcastReceiver
    {
        private LocationData _data;
        private Logging.Logging _logger = new Logging.Logging();

        public override void OnReceive(Context context, Intent intent)
        {
            GetLocationData();
        }

        private void SaveDataToDb(LocationData data)
        {
            App.Database.SaveLocationDataToDbAsync(data);
        }

        private async void GetLocationData()
        {
            if (this._data == null)
                this._data = new LocationData();


            try
            {
                var location = await Geolocation.GetLocationAsync();
                if (location == null)
                    location = await Geolocation.GetLastKnownLocationAsync();

                if (location != null)
                {
                    this._data.Latitude = location.Latitude;
                    this._data.Longitude = location.Longitude;

                    var placemark = (await Geocoding.GetPlacemarksAsync(
                        location.Latitude, location.Longitude))?.FirstOrDefault();
                    if (placemark != null)
                    {
                        this._data.Locality = placemark.Locality;
                        this._data.ZipCode = placemark.PostalCode;
                        this._data.AdminArea = placemark.AdminArea;
                        this._data.Country = placemark.CountryName;
                    }
                }
                this._data.CreationDate = DateTime.Now;
                SaveDataToDb(this._data);
            }
            catch (Exception ex)
            {
                this._logger.WriteLogEntry(Logging.LoggingType.ERROR,
                    ex.Message + " GetLocationData() in class PositionServiceDroid");
            }
        }
    }
}

1 Ответ

0 голосов
/ 18 июня 2020

Вы можете использовать Shiny , это реальное средство решения проблем в области фоновых и передних служб в xamarin. блестящий начало работы

...