简体   繁体   English

在 Delphi 10.3 中启动前台服务

[英]Start Foreground service in Delphi 10.3

I need to start a service for Android 9 in foreground but notification is not working.我需要在前台为 Android 9 启动一项服务,但通知不起作用。 I tried this code but this error occurs when the service starts: "invalid channel for service notification".我尝试了此代码,但是在服务启动时发生此错误:“服务通知的通道无效”。 I am using Delphi 10.3.我正在使用 Delphi 10.3。 Any idea to solve this issue?有什么想法可以解决这个问题吗?

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;

Now this code would take several pages to describe in full.现在这段代码需要几页才能完整描述。 You're welcome to use whatever parts suit your app.欢迎您使用适合您的应用程序的任何部分。 This is working code from my app that's running on dozens of phones from 4.4.2 up.这是我的应用程序中的工作代码,它运行在 4.4.2 以上的数十部手机上。 This code compiles under Delphi 10.2.3 for API 14 and Delphi 10.3.3 for API 28.此代码在 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