Delphi Seattle Android TNotificationCenter CancelAll not working after one notification has fired

笑着哭i 提交于 2019-12-11 00:26:16

问题


I'm using Delphi DX Seattle and testing on an android Device
when a user clicks a button i'm creating multiple scheduled notifications
and when a user clicks another button im clearing the remaining notifications

I cant seem to get the TNotificationCenter.CancelAll to actually cancel notifications after one notification has fired
Similar Question Here

Using the Delphi sample SendCancelNotification as the base code
I'm Changing the "Send Notification Immediately" button to "Send Multiple Notifications" and the code looks like this

procedure TNotificationsForm.btnSendMultipleNotificationsClick(
  Sender: TObject);

  procedure MyNotificationCreate(aNotificationName : String; aSecondDelay : Word);
  var
    Notification: TNotification;
  begin
    if (aSecondDelay < 0) or (aSecondDelay > 60) then
      raise Exception.Create('Seconds must be between 0 and 60');
    { verify if the service is actually supported }
    Notification := NotificationC.CreateNotification;
    try
      Notification.Name := aNotificationName;
      Notification.AlertBody := aNotificationName + ' ran after ' + inttostr(aSecondDelay) + ' seconds';

      { Fired in 10 second }
      Notification.FireDate := Now + EncodeTime(0,0,aSecondDelay,0);

      { Send notification in Notification Center }
      NotificationC.ScheduleNotification(Notification);
    finally
      Notification.DisposeOf;
    end;
  end;
begin
  MyNotificationCreate('First' , 5);
  MyNotificationCreate('Second', 10);
  MyNotificationCreate('Third' , 15);
end;

This sends three notifications after the button has been clicked.
if i click the "Send Multiple Notifications" button and then before 5 seconds click the "cancel all notifications" button the notifications are canceled successfully.

procedure TNotificationsForm.SpeedButton2Click(Sender: TObject);
begin
  NotificationC.CancelAll;
end;    

But if i click the multi notification button and wait until the first notification has fired then click the "cancel all notifications" button, it doesn't cancel the remaining notifications. e.g. notifications Second and Third still run.

Has anyone come across this? or have any ideas on why the CancelAll event doesn't work after one of the notifications have been sent


回答1:


I have found the issue and have got it to work
this solution requires you to not have a numerical number as the first character of your notification name
if you can think of a better way to resolve this issue please post your answer

if you are running into the same issue then copy the System.Android.Notification.pas from Source code here file into your project folder and give it a go

after sending off three or more notifications and the first notification is triggered on android the notifications were loosing the #10 character.

e.g. one=10#10Two=11#10Three=12 was becoming Two=11Three=12 and then the cancel all was not getting a name match and never canceling two or three

I have copied the
Embarcadero\Studio\17.0\source\rtl\common\System.Android.Notification.pas
file to my project file and modified it to help make more sense of what was happening

this is the function that i was using to help track down the problem

function TAndroidPreferenceAdapter.GetAllNotificationsNames: TStringList;
var
  Notifications: TStringList;
  NotificationsStr: JString;
  I: Integer;
begin
  Notifications := TStringList.Create;
  NotificationsStr := FPreference.getString(TJNotificationAlarm.JavaClass.SETTINGS_NOTIFICATION_IDS, nil);
  Notifications.Text := JStringToString(NotificationsStr);
  for I := 0 to Notifications.Count - 1 do
    Notifications[I] := ExtractName(Notifications[I]);

  Result := Notifications;
end;

what i ended up doing was to check for more than 1 = character in the string list loop
if there were more than 1, Delete the original line then loop through the original string from the = character until a non numeric number occurred and re insert that into the string list

function TAndroidPreferenceAdapter.GetAllNotificationsNamesNonFiltered: TStringList;
var
  Notifications: TStringList;
  NotificationsStr: JString;
  I: Integer;
  function OccurrencesOfChar(const S: string; const C: char): integer;
  var
    i: Integer;
  begin
    result := 0;
    for i := 1 to Length(S) do
      if S[i] = C then
        inc(result);
  end;

  function InsertLineBreaks(const S: string) : String;
  var sNewString, sRemaining : String;

      i : integer;
      const validChars = '0123456789';
  begin
    try
      sNewString := '';
      sRemaining := S;
      for I := pos('=',sRemaining,1) to length(sRemaining) -1 do begin
        if pos( sRemaining[i], validChars ) > 0 then begin
          //continue as its still an integer
        end else begin
          sNewString := copy( sRemaining, 0, i);
          sRemaining := copy( sRemaining, i+1, Length(s));
          if OccurrencesOfChar(sRemaining, '=') > 1  then begin
            InsertLineBreaks(sRemaining);
            sRemaining := '';
          end;
          break;
        end;
      end;
      if sNewString <> '' then
        Notifications.Add( sNewString ) ;
      if sRemaining <> '' then
        Notifications.Add( sRemaining ) ;
      Result := sNewString + sRemaining;
    except
      on E:Exception do begin
        e.Message := e.Message + #13#10 + 'fn[TAndroidPreferenceAdapter.GetAllNotificationsNamesNonFiltered.InsertLineBreaks]';
        raise;
      end;
    end;
  end;
var sTemp : String;
begin
  Notifications := TStringList.Create;
  NotificationsStr := FPreference.getString(TJNotificationAlarm.JavaClass.SETTINGS_NOTIFICATION_IDS, nil);
  Notifications.Text := JStringToString(NotificationsStr);

  for I := 0 to Notifications.Count - 1 do begin
    if OccurrencesOfChar(Notifications[I], '=') > 1 then begin
      sTemp := Notifications[I];
      Notifications.Delete( i );
      InsertLineBreaks( sTemp );
      break;
    end;
  end;

  Result := Notifications;
end;

i also had to change anywhere that was calling the

Notifications := TStringList.Create;
NotificationsStr := FPreference.getString(TJNotificationAlarm.JavaClass.SETTINGS_NOTIFICATION_IDS, nil);
Notifications.Text := JStringToString(NotificationsStr);

to the new GetAllNotificationsNamesNonFiltered

have a look at the source code if something above doesn't make sense Source code here



来源:https://stackoverflow.com/questions/35906638/delphi-seattle-android-tnotificationcenter-cancelall-not-working-after-one-notif

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!