繁体   English   中英

在 Delphi 10.3 中启动前台服务

[英]Start Foreground service in Delphi 10.3

我需要在前台为 Android 9 启动一项服务,但通知不起作用。 我尝试了此代码,但是在服务启动时发生此错误:“服务通知的通道无效”。 我正在使用 Delphi 10.3。 有什么想法可以解决这个问题吗?

procedure TServiceModule.StartForeground;
var
  LBuilder: JNotificationCompat_Builder;
begin
  LBuilder := TJNotificationCompat_Builder.JavaClass.init(TAndroidHelper.Context);
  LBuilder.setAutoCancel(True);
  LBuilder.setContentTitle(StrToJCharSequence('Title'));
  LBuilder.setContentText(StrToJCharSequence('Text'));
  LBuilder.setSmallIcon(TAndroidHelper.Context.getApplicationInfo.icon);
  LBuilder.setTicker(StrToJCharSequence('Caption'));
  TJService.Wrap(System.JavaContext).startForeground(1413, LBuilder.build);
end;

现在这段代码需要几页才能完整描述。 欢迎您使用适合您的应用程序的任何部分。 这是我的应用程序中的工作代码,它运行在 4.4.2 以上的数十部手机上。 此代码在 API 14 的 Delphi 10.2.3 和 API 28 的 Delphi 10.3.3 下编译。

uses
   Androidapi.JNI.App,
   Androidapi.JNI.GraphicsContentViewText,
   Androidapi.JNI.Support;

function TMainService.AndroidServiceStartCommand(const Sender: TObject;
     const Intent: JIntent; Flags, StartId: Integer): Integer;
var
  ExtraData: String;
  {$ifdef VER330}
  ServiceChannel: JNotificationChannel;
  NotificationManager: JNotificationManager;
  Obj: JObject;
  {$endif}
  NewIntent: JIntent;
  ncb: JNotificationCompat_Builder;
  ntf: JNotification;
  PendingIntent: JPendingIntent;

begin

   Result := TJService.JavaClass.START_NOT_STICKY;

   // can't ref .O on earlier phones, must hardcode
  if TJBuild_VERSION.JavaClass.SDK_INT > 26 then // JBuild_VERSION_CODES.JavaClass.O                    begin
    {$ifdef VER330}
    // new ways for SDK > 26 (won't be called when API < 26 anyways)
    ServiceChannel := TJNotificationChannel.JavaClass.init(
      StringtoJString(CHANNEL_ID),
      StrToJCharSequence('My Service Channel'),
      TJNotificationManager.JavaClass.IMPORTANCE_DEFAULT
    );

    Obj := TAndroidHelper.Context.getSystemService(
    TJContext.JavaClass.NOTIFICATION_SERVICE);
    NotificationManager := TJNotificationManager.Wrap(Obj);
    NotificationManager.createNotificationChannel(ServiceChannel);

    NewIntent:= TAndroidHelper.Context.getPackageManager().getLaunchIntentForPackage(
      TAndroidHelper.Context.getPackageName());
    NewIntent.setAction(TJIntent.JavaClass.ACTION_MAIN);
    NewIntent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);
    NewIntent.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent := TJPendingIntent.JavaClass.getActivity(
      TAndroidHelper.Context, 0, NewIntent,
      TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK
    );

    ncb := TJNotificationCompat_Builder.JavaClass.init(
      TAndroidHelper.Context,
      StringToJString(CHANNEL_ID)
    );

   ncb.setContentTitle(StrToJCharSequence('MyService'));
   // ncb.setTicker(StrToJCharSequence('MyCommsService')); // can't remember why this is commented out to be honest
   ncb.setSmallIcon(JavaService.getApplicationInfo.icon);
   ncb.setContentIntent(PendingIntent);
   ncb.setOngoing(True);
   ntf := ncb.build;
   {$endif VER330}
 end
 else
 begin
   {$ifdef ORDINARY_NOTIFICATION}
    PendingIntent := TJPendingIntent.JavaClass.getActivity(
      JavaService.getApplicationContext, 0, Intent, 0
    );
    ntf := TJNotification.Create;
    ntf.icon := JavaService.getApplicationInfo.icon;
    ntf.setLatestEventInfo(
      JavaService.getApplicationContext,
      StrToJCharSequence('MyService'),
      StrToJCharSequence('MyCommsService'), PendingIntent);
    {$endif}
    {$ifdef CLICKABLE_NOTIFICATION}
    NewIntent:= TAndroidHelper.Context.getPackageManager().getLaunchIntentForPackage(
      TAndroidHelper.Context.getPackageName());
    NewIntent.setAction(TJIntent.JavaClass.ACTION_MAIN);
    NewIntent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);
    NewIntent.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent := TJPendingIntent.JavaClass.getActivity(
      TAndroidHelper.Context, 0, NewIntent,
      TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK
    );

    ncb := TJNotificationCompat_Builder.JavaClass.init(TAndroidHelper.Context);
    ncb.setContentTitle(StrToJCharSequence('MyService'));
    ncb.setTicker(StrToJCharSequence('MyCommsService'));
    ncb.setSmallIcon(JavaService.getApplicationInfo.icon);
    ncb.setContentIntent(PendingIntent);
    ncb.setOngoing(True);
    ntf := ncb.build;
    {$endif}
  end;

  JavaService.startForeground(StartId, ntf);

  if Intent <> nil then
  begin
     ExtraData := TAndroidHelper.JStringToString(
       Intent.getStringExtra(TAndroidHelper.StringToJString('ExtraData')));
  end;
end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM