Я новичок в программировании на 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");
}
}
}
}