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

如何在Delphi 10.4.2中实现Android后台读取推送通知?

Delphi 10.4.2 Android 后台推送自动执行任务解决方案

要实现推送到达时后台自动执行指定逻辑,核心要解决 Android 后台限制、Firebase 消息类型适配以及 Delphi 与原生 Android 代码交互这几个问题,具体步骤如下:

1. 确保推送为「数据消息」而非「通知消息」

Android 系统对两类 Firebase 推送的处理逻辑完全不同:

  • 通知消息:后台状态下由系统接管展示,不会触发应用代码,仅用户点击后才会唤醒应用。
  • 数据消息:无论前台/后台,都会直接传递给应用的 Firebase 消息处理服务,是实现后台自动执行的前提。

推送 payload 示例(仅包含 data 字段):

{
  "data": {
    "action": "run_task",
    "param1": "value1"
  },
  "to": "目标设备Token"
}

2. 自定义 FirebaseMessagingService 处理后台消息

Delphi 默认的 Firebase 消息处理在后台场景下存在限制,需自定义原生 Android Service 来接管消息接收:

步骤2.1 编写 Java 服务类

创建 MyFirebaseMessagingService.java,继承 FirebaseMessagingService 并重写 onMessageReceived 方法:

package com.yourcompany.yourapp; // 替换为你的应用包名

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import android.os.PowerManager;
import android.content.Context;

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // 获取推送指令
        String action = remoteMessage.getData().get("action");
        
        // 唤醒设备,防止休眠中断任务
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp:PushWakeLock");
        wakeLock.acquire(60000); // 锁定1分钟,可根据任务时长调整
        
        try {
            // 触发Delphi端任务逻辑
            if ("run_task".equals(action)) {
                DelphiPushCallback.executeTask();
            }
        } finally {
            wakeLock.release();
        }
    }
}

将该类编译为 Jar 文件,放入 Delphi 项目的 libs 目录,并在项目选项「Android → Libraries」中添加此 Jar。

步骤2.2 配置 AndroidManifest

修改项目的 AndroidManifest.template.xml,添加权限、注册自定义服务:

<!-- 添加必要权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<!-- 注册自定义Firebase消息服务 -->
<service android:name="com.yourcompany.yourapp.MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

3. Delphi 端实现 JNI 回调

通过 JNI 让 Java 服务调用 Delphi 代码,执行指定任务:

步骤3.1 编写 Delphi 回调单元

unit PushCallback;

interface

implementation

uses
  Androidapi.JNIBridge, Androidapi.JNI.JavaTypes, Androidapi.Helpers,
  Androidapi.JNI.Os, System.SysUtils;

// 供Java调用的任务执行方法
procedure ExecuteTask; cdecl; export;
begin
  // 此处编写你需要自动运行的逻辑
  // 例:启动后台服务、执行数据同步等
  if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.O then
    TAndroidHelper.Context.startForegroundService(
      TJIntent.JavaClass.init(TAndroidHelper.Context, TMyBackgroundService.ClassContext)
    )
  else
    TAndroidHelper.Context.startService(
      TJIntent.JavaClass.init(TAndroidHelper.Context, TMyBackgroundService.ClassContext)
    );
end;

// 导出方法名需与Java调用路径一致:Java_包名_类名_方法名
exports
  ExecuteTask name 'Java_com_yourcompany_yourapp_DelphiPushCallback_executeTask';

end.

步骤3.2 处理 Android 8.0+ 后台限制

Android 8.0 及以上版本禁止后台长时间运行服务,需将任务放在前台服务中执行:

  1. 创建 Delphi 后台服务 TMyBackgroundService(继承 TAndroidService)
  2. 在服务的 OnCreate 方法中启动前台通知:
procedure TMyBackgroundService.ServiceCreate(Sender: TObject);
var
  ChannelID: JString;
  NotificationChannel: JNotificationChannel;
  NotificationManager: JNotificationManager;
  Builder: JNotificationCompat_Builder;
begin
  ChannelID := StringToJString('background_task_channel');
  
  // 创建通知渠道(Android 8.0+ 必需)
  if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.O then
  begin
    NotificationChannel := TJNotificationChannel.JavaClass.init(
      ChannelID, StringToJString('后台任务'), TJNotificationManager.JavaClass.IMPORTANCE_LOW
    );
    NotificationManager := TJNotificationManager.Wrap(
      TAndroidHelper.Context.getSystemService(TJContext.JavaClass.NOTIFICATION_SERVICE)
    );
    NotificationManager.createNotificationChannel(NotificationChannel);
  end;

  // 构建前台通知
  Builder := TJNotificationCompat_Builder.JavaClass.init(TAndroidHelper.Context, ChannelID);
  Builder.setContentTitle(StringToJString('执行后台任务'));
  Builder.setContentText(StringToJString('处理推送请求'));
  Builder.setSmallIcon(TAndroidHelper.Context.getApplicationInfo.icon);

  // 启动前台服务
  startForeground(1001, Builder.build);
end;

4. 额外注意事项

  • 将应用加入设备电池优化白名单,避免系统杀死后台服务。
  • 测试时确保设备处于锁屏/后台状态,验证任务是否自动执行。
  • 若任务耗时较短,可直接在 ExecuteTask 中执行,无需启动前台服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:40:31