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

Delphi开发App适配Android 8(API26)后后台推送失效求助

解决Delphi中targetSdkVersion升级到26后推送通知失效的问题

Hey Juan, 我之前在Delphi开发Android应用时也碰到过完全一样的问题——升级targetSdkVersion到26后,后台推送直接罢工,折腾了好一阵才搞定。结合Android 8.0的新限制和Delphi的适配逻辑,给你梳理下问题根源和解决办法:

问题根源

你猜的没错,Android 8.0(API 26)的后台执行限制和通知渠道强制要求是核心原因:

  • 后台服务限制:Android O彻底收紧了后台服务的运行权限,之前依赖后台静默服务接收推送的逻辑会被系统直接终止
  • 通知渠道要求:从O开始,所有推送通知必须绑定到一个已创建的通知渠道,没有渠道的通知系统会直接忽略,根本不会展示给用户

分步解决方案

1. 先搞定通知渠道(最关键的第一步)

在应用启动时必须创建对应的通知渠道,否则任何推送都无法显示。在Delphi里可以这么写:

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

procedure TMainForm.FormCreate(Sender: TObject);
begin
  CreateNotificationChannel;
end;

procedure TMainForm.CreateNotificationChannel;
var
  NotificationManager: JNotificationManager;
  Channel: JNotificationChannel;
  ChannelID, ChannelName, ChannelDesc: string;
begin
  // 只在Android 8.0及以上版本执行
  if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.O then
  begin
    ChannelID := 'push_notification_channel';
    ChannelName := '推送通知';
    ChannelDesc := '接收应用的推送消息';

    // 获取通知管理器实例
    NotificationManager := TJNotificationManager.Wrap(
      TAndroidHelper.Context.getSystemService(TJContext.JavaClass.NOTIFICATION_SERVICE));

    // 创建渠道
    Channel := TJNotificationChannel.JavaClass.init(
      StringToJString(ChannelID),
      StringToJString(ChannelName),
      TJNotificationManager.JavaClass.IMPORTANCE_DEFAULT);
    Channel.setDescription(StringToJString(ChannelDesc));

    // 注册渠道到系统
    NotificationManager.createNotificationChannel(Channel);
  end;
end;

记得在推送时指定这个渠道ID,比如构建通知时调用setChannelId(StringToJString('push_notification_channel'))。

2. 调整推送服务的运行方式

如果你的推送是自定义的后台服务,现在必须改成前台服务才能在后台存活:

  • 在服务的onCreate或onStartCommand方法里调用startForeground(),绑定一个低优先级的通知(避免打扰用户):
procedure TMyPushService.ServiceCreate(Sender: TObject);
var
  Notification: JNotification;
begin
  if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.O then
  begin
    // 构建前台服务通知(用之前创建的渠道ID)
    Notification := TJNotificationCompat_Builder.JavaClass.init(TAndroidHelper.Context, StringToJString('push_notification_channel'))
      .setContentTitle(StringToJString('应用运行中'))
      .setContentText(StringToJString('正在接收推送'))
      .setSmallIcon(ResourceIDToJDrawable(Icon))
      .build;

    // 启动前台服务,通知ID随便设一个不重复的数字
    startForeground(1001, Notification);
  end;
end;
  • 更推荐的做法是迁移到Firebase Cloud Messaging(FCM):Delphi官方对FCM有完善支持,FCM会通过系统级的服务处理推送,完全不受Android O的后台限制影响,适配成本更低。

3. 补全AndroidManifest的权限和配置

  • 新增前台服务权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  • 如果用FCM,确保Manifest里包含FCM的接收器和服务配置(Delphi的FCM组件会自动生成,但手动检查更稳妥):
<receiver
    android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="${applicationId}" />
    </intent-filter>
</receiver>
<service
    android:name="com.google.firebase.iid.FirebaseInstanceIdService"
    android:exported="true">
    <intent-filter android:priority="-500">
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>

测试注意事项

  • 一定要在Android 8.0+的设备上测试,模拟后台状态(按Home键退出,或者强制停止应用后触发推送)
  • 尽量不要依赖旧版SDK(24.3.3)的兼容逻辑,建议升级Delphi的Android SDK组件到API 26及以上,减少兼容性坑

按照这些步骤调整后,你的推送应该就能正常工作了,而且能满足Google Play的targetSdkVersion要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:07:33