我正在开发适用于Android,iOS和Windows Phone的Xamarin应用。此应用应在指定时间显示本地通知。对于Android我使用AlamManager。通知适用于iOS,WinPhone和Android Emulators。在我的设备(三星Galaxy S2)上,仅在近期(1分钟,5分钟,20分钟)通知工作。不会出现约45分钟或更长时间的通知。有时会出现约30分钟的通知,有时也不会出现。通知在广播接收器中进行。我的代码或alarmManager有问题吗?找不到任何东西。谢谢你的帮助。
这里设置了alarmManager:
public class NotificationService : NotificationServiceBase
{
private readonly AlarmManager _alarmManager;
private readonly long _dayInMilliseconds = AlarmManager.IntervalDay;
private PendingIntent _currentPendingIntent;
public NotificationService()
{
_alarmManager = (AlarmManager) Forms.Context.GetSystemService(Context.AlarmService);
}
public override void CancelNotification()
{
_alarmManager.Cancel(_currentPendingIntent);
}
protected override void ChangeNotificationTime(TaskEntity task)
{
var settings = _settingsBusinessLayer.GetSettings();
NotificationSetup(settings, task);
}
protected override async void ChangeNotificationSettings(SettingsEntity settings)
{
if (!settings.IsReminderOn)
{
CancelNotification();
return;
}
var task = await _taskBusinessLayer.GetTaskForCurrentMonthAsync(true, true);
NotificationSetup(settings, task);
}
private void NotificationSetup(SettingsEntity settings, TaskEntity task)
{
_currentPendingIntent = GetPendingIntent();
_alarmManager.Cancel(_currentPendingIntent);
if (settings.ReminderRepetitive == ReminderRepetitive.Daily)
{
SetDailyAlarm(settings);
}
else
{
SetSingleAlarm(settings, task);
}
}
private void SetDailyAlarm(SettingsEntity settings)
{
long alarmTimeInMilliseconds;
if (settings.RemindOn < DateTime.Now.TimeOfDay)
{
alarmTimeInMilliseconds = (long) CalculateAlarmTimeFromNow
(DateTime.Now.AddDays(1), 0, settings.RemindOn).TotalMilliseconds;
}
else
{
alarmTimeInMilliseconds = (long) CalculateAlarmTimeFromNow
(DateTime.Now, 0, settings.RemindOn).TotalMilliseconds;
}
var alarmTime = SystemClock.ElapsedRealtime() + alarmTimeInMilliseconds;
_alarmManager.SetRepeating(AlarmType.ElapsedRealtime, alarmTime, _dayInMilliseconds, _currentPendingIntent);
}
private void SetSingleAlarm(SettingsEntity settings, TaskEntity task)
{
try
{
var alarmTimeInMilliseconds = (long) CalculateAlarmTimeFromNow
(task.DueDate, Convert.ToUInt32(settings.RemindDaysBefore), settings.RemindOn).TotalMilliseconds;
var alarmTime = SystemClock.ElapsedRealtime() + alarmTimeInMilliseconds;
_alarmManager.Set(AlarmType.ElapsedRealtime, alarmTime, _currentPendingIntent);
}
catch (AlarmTimeIsInPastException)
{
}
}
private PendingIntent GetPendingIntent()
{
var alarmIntent = new Intent(Forms.Context, typeof (NotificationReceiver));
return PendingIntent.GetBroadcast(Forms.Context, 0, alarmIntent,
PendingIntentFlags.UpdateCurrent);
}
}
广播接收器,发出通知。
[BroadcastReceiver]
public class NotificationReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var taskBusinessLayer = DependencyInjection.Container.Resolve<ITaskBusinessLayer>();
var task = taskBusinessLayer.GetTaskForCurrentMonthAsync(true, true).Result;
var message = NotificationServiceBase.CreateNotificationMessageRemainingTime(task);
var title = AppResources.NotificationTitle;
var notIntent = new Intent(context, typeof (MainActivity));
var contentIntent = PendingIntent.GetActivity(context, 0, notIntent, PendingIntentFlags.CancelCurrent);
var builder = new Notification.Builder(context)
.SetContentIntent(contentIntent)
.SetContentTitle(title)
.SetContentText(message)
.SetSmallIcon(Resource.Drawable.icon)
.SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate)
.SetPriority((int) NotificationPriority.Max)
.SetAutoCancel(true)
.SetWhen(JavaSystem.CurrentTimeMillis());
var notification = builder.Build();
var notificationManager = NotificationManager.FromContext(context);
const int notificationId = 0;
notificationManager.Notify(notificationId, notification);
}
}
答案 0 :(得分:0)
从KITKAT开始的警报传递是不准确的。所以你可能需要改变你的SetSingleAlarm方法:
_alarmManager.Set(AlarmType.ElapsedRealtime, alarmTime, _currentPendingIntent);
到此:
if (Build.VERSION.SdkInt < BuildVersionCodes.Kitkat)
{
_alarmManager.Set(AlarmType.ElapsedRealtime, alarmTime, _currentPendingIntent);
}
else
{
_alarmManager.SetExact(AlarmType.ElapsedRealtime, alarmTime, _currentPendingIntent);
}