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

Unity3D中配置OneSignal:接收通知但后台不显示

解决Unity3D+Firebase+OneSignal:仅在应用运行时接收通知的问题

我之前也遇到过类似的需求,结合OneSignal和Unity的特性,给你整理了一套可行的方案:

核心思路

要实现「仅应用运行时显示通知」,关键在于拦截通知的展示逻辑:只在应用处于活跃状态(前台/后台进程存活)时处理通知弹窗,应用完全未运行时直接跳过展示,仅按需处理数据内容。

步骤1:调整Firebase消息发送类型

首先要确保你通过Firebase发送的是**数据消息(Data Message)**而非通知消息(Notification Message)。因为通知消息会被Android系统自动触发展示,不受客户端控制;而数据消息完全由我们的代码决定如何处理,更适配需求。

修改你现有的Firebase发送代码,把所有通知内容放到data字段中,避免使用notification字段:

var sendNotification = (data) => {
  var headers = {
    "Content-Type": "application/json; charset=utf-8",
    "Authorization": "key=YOUR_FIREBASE_SERVER_KEY"
  };
  var payload = {
    to: "TARGET_DEVICE_TOKEN",
    data: { // 所有通知内容、自定义数据都放在这里
      title: "你的通知标题",
      body: "你的通知内容",
      customKey: "自定义业务数据"
    }
  };
  // 后续发送请求的逻辑保持不变...
};

步骤2:Unity中集成OneSignal的通知拦截逻辑

在Unity里注册OneSignal的通知接收回调,在回调中判断应用运行状态,决定是否展示通知:

using UnityEngine;
using OneSignalSDK;

public class NotificationManager : MonoBehaviour
{
    void Start()
    {
        // 初始化OneSignal(确保已完成基础配置)
        OneSignal.Initialize("YOUR_ONESIGNAL_APP_ID");
        
        // 注册通知接收拦截回调
        OneSignal.Notifications.Received += OnNotificationReceived;
    }

    private void OnNotificationReceived(NotificationReceivedEvent notificationEvent)
    {
        // 判断应用是否处于运行状态:前台聚焦 或 后台进程存活
        bool isAppRunning = Application.isFocused || IsAppInBackground();

        if (!isAppRunning)
        {
            // 应用未运行,取消通知展示
            notificationEvent.Cancel = true;
            Debug.Log("应用未运行,跳过通知展示");
            return;
        }
        
        // 应用运行中,可选择让OneSignal默认展示,或自定义Unity UI弹窗
        Debug.Log("应用运行中,展示通知:" + notificationEvent.Notification.Title);
    }

    // 辅助方法:判断Android应用是否在后台存活
    private bool IsAppInBackground()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        AndroidJavaClass activityManager = new AndroidJavaClass("android.app.ActivityManager");
        AndroidJavaObject appTasks = activityManager.CallStatic<AndroidJavaObject>("getService").Call<AndroidJavaObject>("getAppTasks");
        
        foreach (AndroidJavaObject task in appTasks.Call<AndroidJavaObject>("toArray"))
        {
            AndroidJavaObject taskInfo = task.Call<AndroidJavaObject>("getTaskInfo");
            int state = taskInfo.Get<int>("state");
            // 状态为2表示应用在后台存活
            if (state == 2) return true;
        }
#endif
        return false;
    }
}

步骤3:Android端后台逻辑加固

如果需要更严格控制后台场景的通知展示,可以自定义OneSignal的NotificationService来拦截:

  1. 在Unity的Android插件目录下创建CustomNotificationService.java:
import com.onesignal.OSNotificationReceivedEvent;
import com.onesignal.OneSignal;
import android.app.ActivityManager;
import android.content.Context;
import java.util.List;

public class CustomNotificationService extends OneSignal.OSNotificationReceivedHandler {
    @Override
    public void notificationReceived(OSNotificationReceivedEvent event) {
        Context context = event.getApplicationContext();
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
        
        boolean isAppRunning = false;
        for (ActivityManager.RunningAppProcessInfo process : runningProcesses) {
            if (process.processName.equals(context.getPackageName()) && process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                isAppRunning = true;
                break;
            }
        }

        if (!isAppRunning) {
            // 应用未在前台运行,取消通知
            event.complete(null);
            return;
        }
        
        // 应用运行中,允许通知展示
        event.complete(event.getNotification());
    }
}
  1. 在AndroidManifest.xml中注册该Service:
<service
    android:name=".CustomNotificationService"
    android:permission="android.permission.BIND_JOB_SERVICE">
    <intent-filter>
        <action android:name="com.onesignal.NotificationReceived" />
    </intent-filter>
</service>

验证场景

完成配置后测试两种核心场景:

  • 应用前台运行:发送数据消息,正常弹出通知
  • 应用完全退出(杀死进程):发送数据消息,无通知弹窗,重新打开应用后可按需处理数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:31:14