You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 10.3如何在Android Oreo中启动前台服务?

在Delphi 10.3中实现Android Oreo前台服务的完整方案

我来帮你搞定这个问题——Android Oreo(API 26+)对后台服务的限制确实挺严格的,你现在的代码只是启动了普通服务,还没适配前台服务的要求,下面分应用端和服务端一步步给你调整:

一、应用端:改用startForegroundService启动服务

原来用TLocalServiceConnection.StartService在Oreo及以上版本会被系统限制,必须判断系统版本,调用Android原生的startForegroundService方法:

uses
  Androidapi.JNI.App, Androidapi.JNI.Os, Androidapi.Helpers,
  Androidapi.JNI.GraphicsContentViewText;

// 替换你原来的启动服务代码
procedure TMainForm.StartMyService;
var
  LIntent: JIntent;
begin
  // 判断Android版本是否为Oreo及以上
  if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.O then
  begin
    // 构建启动服务的Intent,这里的TJDM是你服务类(TDM)对应的Java类
    LIntent := TJIntent.JavaClass.init(TAndroidHelper.Context, TJDM.JavaClass);
    // 调用前台服务启动方法
    TAndroidHelper.Context.startForegroundService(LIntent);
  end
  else
  begin
    // 低版本继续用原来的TLocalServiceConnection方式
    FService := TLocalServiceConnection.Create;
    FService.StartService('MySvc');
  end;
end;

二、服务端:在AndroidServiceStartCommand中启动前台

服务启动后必须在5秒内调用startForeground,否则系统会直接杀死服务,同时Oreo要求通知必须绑定通知渠道,所以我们需要先创建渠道,再构建通知:

1. 先添加创建通知渠道的方法

在你的TDM类中新增一个私有方法:

procedure TDM.CreateNotificationChannel;
var
  LChannel: JNotificationChannel;
  LNotificationManager: JNotificationManager;
begin
  if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.O then
  begin
    // 获取通知管理器
    LNotificationManager := TJNotificationManager.Wrap(
      TAndroidHelper.Context.getSystemService(TJContext.JavaClass.NOTIFICATION_SERVICE));
    // 创建通知渠道,ID和名称可以自定义
    LChannel := TJNotificationChannel.JavaClass.init(
      'ForegroundService_Channel',
      StrToJCharSequence('前台服务通知'),
      TJNotificationManager.JavaClass.IMPORTANCE_LOW); // 选低重要性避免打扰用户
    LChannel.setDescription(StrToJCharSequence('用于维持前台服务运行'));
    // 注册渠道
    LNotificationManager.createNotificationChannel(LChannel);
  end;
end;

2. 修改AndroidServiceStartCommand方法

更新你的服务启动命令处理逻辑,加入前台服务的启动代码:

function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
var
  LNotificationBuilder: JNotificationCompat_Builder;
  LNotification: JNotification;
  LPendingIntent: JPendingIntent;
  LLaunchIntent: JIntent;
  LIconResId: Integer;
begin
  // 第一步:创建通知渠道(Oreo+必需)
  CreateNotificationChannel;

  // 第二步:构建点击通知后打开主界面的Intent
  LLaunchIntent := TAndroidHelper.Context.getPackageManager.getLaunchIntentForPackage(
    TAndroidHelper.Context.getPackageName);
  LPendingIntent := TJPendingIntent.JavaClass.getActivity(TAndroidHelper.Context, 0, LLaunchIntent, 0);

  // 第三步:获取通知小图标(注意要用符合Android规范的白色透明图标)
  LIconResId := TAndroidHelper.Context.getResources.getIdentifier('ic_launcher', 'drawable', TAndroidHelper.Context.getPackageName);

  // 第四步:构建前台通知
  LNotificationBuilder := TJNotificationCompat_Builder.JavaClass.init(TAndroidHelper.Context, 'ForegroundService_Channel');
  LNotificationBuilder.setContentTitle(StrToJCharSequence('我的前台服务'))
    .setContentText(StrToJCharSequence('服务正在后台运行'))
    .setSmallIcon(LIconResId)
    .setContentIntent(LPendingIntent)
    .setOngoing(True); // 设置为不可手动取消,除非服务停止

  // 第五步:启动前台服务,第一个参数是通知ID(只要唯一就行)
  startForeground(1001, LNotificationBuilder.build);

  // 保持服务被杀死后自动重启
  Result := TJService.JavaClass.START_STICKY;
end;

3. 服务停止时清理前台状态

在TDM的AndroidServiceDestroy事件中添加停止前台的代码,避免通知残留:

procedure TDM.AndroidServiceDestroy(Sender: TObject);
begin
  // 停止前台服务并移除通知
  stopForeground(True);
end;

三、必要的权限配置

别忘了在AndroidManifest中添加前台服务权限:

  1. 打开Project -> Options -> Application -> Permissions
  2. 勾选FOREGROUND_SERVICE权限(如果找不到,也可以手动编辑AndroidManifest.xml,添加<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />)

几个关键注意点:

  • 调用startForegroundService后,服务必须在5秒内调用startForeground,否则系统会终止服务
  • 通知小图标必须符合Android规范(白色透明背景),否则通知可能显示异常
  • 如果你需要停止服务,记得调用stopSelf()或者stopService(),同时会触发stopForeground

内容的提问来源于stack exchange,提问作者Micha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:24:39