Custom notification interval

2019-07-23 14:20发布

问题:

I am building an app in FireMonkey under Rad Studio XE8.

I would like to have custom intervals on my notifications (FMX.Notification).

However notification repeats can only be set to certain intervals.

TRepeatInterval = (None, Second, Minute, Hour, Day, Week, Weekday, Month, Quarter, Year, Era);

If i whant to fire each 15 minutes, would I really need to create four notification (at 0 , 15, 30, 45 minutes) and repeat them every hour with TRepeatInterval(4)?

回答1:

The documentation for FMX.Notification.TNotification.RepeatInterval says, with my emphasis:

If you want to set a custom interval, like for example 30 minutes, you need to create two notifications setting a scheduled difference of 30 minutes with FireDate and set the repeat interval of both notifications to an hour.

You're guessing right. You would need to create four notification and repeat them every hour.


OP told in the comments, that he used following code, in the end. I included it in my answer to improve readability of his given information.

//Repeat very 5 minutes
//Create 12 notifications fireing every hour with 5 minute intervals Notification.RepeatInterval := TRepeatInterval.Hour;
for I := 0 to 11 do
begin
  Notification.FireDate := Notification.FireDate + EncodeTime(0,(I*5),0,0);
  ANotificationcenter.ScheduleNotification(Notification);
end;


回答2:

Just to add to René Hoffmann's answer

The reason why you can only use those Repeat intervals is because you cannot set custom repeat intervals with iOS, because it uses the its UILocalNotification object and its RepeatInterval requires a NSCalendarUnit which is a enumerated type.

https://developer.apple.com/library/ios/documentation/iPhone/Reference/UILocalNotification_Class/#//apple_ref/occ/instp/UILocalNotification/repeatInterval

but Android on the otherhand, if you wanted to make a repeating notification you could use the AlarmManager.setRepeating method so if you wanted to make the native repeating Notification that would work for Android you could do this:

TNotification resides in System.Notification Add a property to it:

{$IFDEF ANDROID}
    RepeatIntervalinMills : Integer;
{$ENDIF}

In TNotification.Create just give it a default value

{$IFDEF ANDROID}
  RepeatIntervalinMills := 0;
{$ENDIF}

Now we need to add the native Android method to set a repeating notification, to do this you need to navigate to System.Android.Notification

find TNotificationCenterAndroid.DoScheduleNotification and now just need to add some code, so that if you didn't specify a RepeatIntervalinMills only the standard Notification is created:

begin
  if not ANotification.Name.IsEmpty and FExternalStore.Contains(ANotification.Name) then
    CancelNotification(ANotification.Name);

  ID := TGeneratorUniqueID.GenerateID;
  PendingIntent := CreateNotificationAlarmIntent(ID);
  FExternalStore.SaveNotification(ANotification, ID);

  if ANotification.RepeatIntervalinMills <> 0 then
  begin
      TAndroidHelper.AlarmManager.setRepeating(TJAlarmManager.JavaClass.RTC_WAKEUP, DateTimeLocalToUnixMSecGMT(ANotification.FireDate),
    ANotification.RepeatIntervalinMills,PendingIntent);
  end
  else
  TAndroidHelper.AlarmManager.&set(TJAlarmManager.JavaClass.RTC_WAKEUP, DateTimeLocalToUnixMSecGMT(ANotification.FireDate),
    PendingIntent);
end;

Now when you create your Notification :

MyNotification := NotificationCenter1.CreateNotification;
    try
        MyNotification.Name := 'MyNotification';
        MyNotification.AlertBody := 'Hello!';
        {$IFDEF IOS}
       //Repeat very 5 minutes
       //Create 12 notifications fireing every hour with 5 minute intervals                    Notification.RepeatInterval := TRepeatInterval.Hour;
       for I := 0 to 11 do
       begin
           Notification.FireDate := Notification.FireDate + EncodeTime(0,(I*5),0,0);
           ANotificationcenter.ScheduleNotification(Notification);
       end;
        {$ENDIF}
        {$IFDEF ANDROID}
        MyNotification.FireDate := IncMinute(Now,5);
        MyNotification.RepeatIntervalinMills := 300000; //Now you can specify your Custom Android Repeat interval
        NotificationCenter1.ScheduleNotification(MyNotification);
        {$ENDIF}
    finally
        MyNotification.DisposeOf;
    end;

This will create a notfication that will fire in 5 mins and will repeat every 5mins