【问题标题】:Delphi Seattle Android TNotificationCenter CancelAll not working after one notification has firedDelphi Seattle Android TNotificationCenter CancelAll 在一个通知触发后不起作用
【发布时间】:2016-03-10 02:44:36
【问题描述】:

我正在使用 Delphi DX Seattle 并在 Android 设备上进行测试
当用户单击按钮时,我正在创建多个预定通知
当用户点击另一个按钮时,我会清除剩余的通知

在一个通知触发后,我似乎无法让 TNotificationCenter.CancelAll 实际取消通知
Similar Question Here

使用 Delphi 示例 SendCancelNotification 作为基本代码
我将“立即发送通知”按钮更改为“发送多个通知”,代码如下所示

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;

这会在单击按钮后发送三个通知。
如果我单击“发送多个通知”按钮,然后在 5 秒前单击“取消所有通知”按钮,则通知已成功取消。

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

但是如果我单击多通知按钮并等到第一个通知触发然后单击“取消所有通知”按钮,它不会取消剩余的通知。例如通知 Second 和 Third 仍在运行。

有人遇到过这个吗?或对发送通知之一后 CancelAll 事件为何不起作用有任何想法

【问题讨论】:

    标签: android delphi notifications firemonkey


    【解决方案1】:

    我找到了问题并解决了问题
    此解决方案要求您不能将数字编号作为通知名称的第一个字符
    如果您能想到更好的方法来解决此问题,请发布您的答案

    如果您遇到同样的问题,请将 Source code here 文件中的 System.Android.Notification.pas 复制到您的项目文件夹中并试一试

    在发送三个或更多通知并在 android 上触发第一个通知后,通知丢失了 #10 字符。

    例如一=10#10二=11#10三=12 变成 Two=11Three=12 然后 cancel all 没有得到名称匹配并且永远不会取消两个或三个

    我已经复制了
    Embarcadero\Studio\17.0\source\rtl\common\System.Android.Notification.pas
    将文件添加到我的项目文件中并对其进行修改以帮助更了解正在发生的事情

    这是我用来帮助追踪问题的函数

    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;
    

    我最终做的是在字符串列表循环中检查多个 1 = 字符
    如果超过 1,则删除原始行,然后从 = 字符循环遍历原始字符串,直到出现非数字数字,然后将其重新插入字符串列表中

    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;
    

    我还必须更改调用

    的任何地方
    Notifications := TStringList.Create;
    NotificationsStr := FPreference.getString(TJNotificationAlarm.JavaClass.SETTINGS_NOTIFICATION_IDS, nil);
    Notifications.Text := JStringToString(NotificationsStr);
    

    到新的 GetAllNotificationsNamesNonFiltered

    如果上面的内容没有意义,请查看源代码Source code here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 1970-01-01
      • 2016-03-05
      相关资源
      最近更新 更多