【发布时间】:2020-10-07 16:39:23
【问题描述】:
我是 Xamarin 和 Android 编程的新手。我目前正在尝试创建一个应用程序,它每晚在凌晨 1 点左右检查设备的位置。时间将使用 TimePicker 在设置页面中设置。我目前面临的唯一挑战是如何安排此任务,以便即使应用程序关闭或设备处于 Dooze 模式,它也能运行。目标平台是 Android 9(Pie)。
到目前为止,我创建了一个前台服务。该前台服务使用 SetRepeading 方法和模式 Rtc_Wakeup 设置 AlarmManager。但这并不像我希望的那样工作!问题是当应用程序设置为后台或关闭时,警报会被触发。但它应该只有在达到触发时间时才被触发。还是我搞错了?
你可以从我的Git Repository获取整个代码
实现这一目标的最佳方法是什么? 谢谢! :)
这是我目前尝试过的 :)
这是我的 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");
}
}
}
}
【问题讨论】:
-
什么不起作用? broadcastReciver 和重复间隔使设备能够运行计划任务,而不管是否运行。
-
究竟是什么问题?检查sample 看看是否有帮助。
-
确切的问题是,如果我已经从我的应用程序启动了前台服务,并且如果我将应用程序置于后台或关闭 id,那么警报会被触发,并且即使启动,BroadcastReciver 中的代码也会被执行即使没有达到方法的触发参数
标签: android xamarin xamarin.forms xamarin.android