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

Xamarin Android应用划掉后无法接收Data-only推送通知求助

应用被划掉关闭后无法接收Firebase Data-only消息的解决方案

问题描述

应用在前台/后台(最小化)时,OnMessageReceived能正常调用并显示通知,但划掉或关闭全部后无法接收Data-only消息,其他商业应用关闭后却能正常接收。使用Xamarin.Firebase.Messaging NuGet包,已签名APK安装在三星S23上,调用Legacy API返回成功但无通知。


现有配置

Android清单

<application android:label="MyTestingApp" android:theme="@style/MainTheme">
    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
    <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>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

自定义FirebaseMessagingService

[Service(Exported = false, Enabled = true, DirectBootAware =true)]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyMessagingService : FirebaseMessagingService{

}

MainActivity的OnStart方法

const int requestLocationId = 0;

string[] notiPermission =
{
    Manifest.Permission.PostNotifications
};

string[] wakePermission =
{
    Manifest.Permission.WakeLock
};

if ((int)Build.VERSION.SdkInt < 33) return;

if (activity.CheckSelfPermission(Manifest.Permission.PostNotifications) != Permission.Granted)
{
    activity.RequestPermissions(notiPermission, requestLocationId);
    activity.RequestPermissions(wakePermission, requestLocationId);
}

Postman测试请求体

{
    "to": "dpm-g36NSEaC5XFadT3ZnY:APA91bEIarlCxz6UEpyY7CYeBsnCSBpXApW6gHEOiVrvk0URkRP4FCqAHmApPFH4KQLDMfYhkkOTTUZ7ZEsRlyKzCPPS9CuLtet9pXi8_DUflE6h_g-iqtD_9DcVQ4amyb1CCfW05vN2",
    "CollapseKey": "1",    
    "data": {
        "body": "Hello,Good Morning! . Have a gr8 day ahead! message_web",
        "title": "Good Morning!)",
        "image": "https://images.pexels.com/photos/2055100/pexels-photo-2055100.jpeg",
        "notificationSmallIcon": "macrokiosk.boldwallet.drawable.logo",
        "notificationSmallIconColor": "#00ff00",
        "notificationLargeIcon" : "https://media.istockphoto.com/id/1352603244/photo/shot-of-an-unrecognizable-businessman-working-on-his-laptop-in-the-office.jpg?s=1024x1024&w=is&k=20&c=mTABddPRSU1r_hCBpknMjJbCIrJAicjjXGSU42rx-YI=",
        "click_action": "web",
        "actionResult": "https://google.com/"
    }
}

额外环境信息

  • Google Play Services版本:118.2.0.5
  • 依赖包:
Xamarin.AndroidX.Core 1.12.0.4
Xamarin.AndroidX.Lifecycle.Common 2.7.0.1
Xamarin.Essentials 1.7.3
Xamarin.CommunityToolkit 2.0.2
Xamarin.Firebase.Messaging 123.3.1.1
Xamarin.Forms 5.0.0.2478
Xamarin.GooglePlayServices.Base 118.0.1

解决方案

1. 适配三星设备的后台权限策略

三星对后台进程有严格管控,需手动设置:

  • 打开「设置」→「应用」→找到目标应用→「电池和设备维护」→「电池」→「后台限制」→设为「无限制」
  • 同一页面开启「自动运行」权限,允许应用后台自启动

2. 优化FirebaseMessagingService配置

修改服务属性,确保进程被杀后能被系统唤醒,并重写消息处理逻辑:

[Service(Exported = true, Enabled = true, DirectBootAware = true)]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
[IntentFilter(new[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new[] { "${applicationId}" })]
public class MyMessagingService : FirebaseMessagingService
{
    public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);
        if (message.Data != null && message.Data.Count > 0)
        {
            ShowNotification(message.Data);
        }
    }

    private void ShowNotification(IDictionary<string, string> data)
    {
        var title = data.ContainsKey("title") ? data["title"] : "通知";
        var body = data.ContainsKey("body") ? data["body"] : "";
        var channelId = "default_channel";

        var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
        
        // Android 8.0+创建通知渠道
        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            var channel = new NotificationChannel(channelId, "默认通知", NotificationImportance.High)
            {
                Description = "应用通知渠道"
            };
            notificationManager.CreateNotificationChannel(channel);
        }

        var intent = PackageManager.GetLaunchIntentForPackage(PackageName);
        intent.AddFlags(ActivityFlags.ClearTop);
        var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable);

        var notificationBuilder = new NotificationCompat.Builder(this, channelId)
            .SetSmallIcon(Resource.Drawable.logo) // 替换为本地图标资源
            .SetContentTitle(title)
            .SetContentText(body)
            .SetAutoCancel(true)
            .SetPriority(NotificationCompat.PriorityHigh)
            .SetContentIntent(pendingIntent);

        notificationManager.Notify(0, notificationBuilder.Build());
    }

    public override void OnNewToken(string token)
    {
        base.OnNewToken(token);
        Log.Debug("FCM Token", token); // 打印最新Token,确保测试用Token有效
    }
}

3. 完善Android清单配置

显式声明自定义服务,补充必要的IntentFilter:

<application android:label="MyTestingApp" android:theme="@style/MainTheme" android:allowBackup="true">
    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
    <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=".MyMessagingService" android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>
</application>

4. 修复权限请求逻辑

按Android版本区分权限请求,确保兼容性:

const int requestNotiId = 1;
const int requestWakeId = 2;

// Android 13+申请通知权限
if ((int)Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu)
{
    if (CheckSelfPermission(Manifest.Permission.PostNotifications) != Permission.Granted)
    {
        RequestPermissions(new[] { Manifest.Permission.PostNotifications }, requestNotiId);
    }
}

// Android 12及以下申请唤醒锁权限
if ((int)Build.VERSION.SdkInt <= BuildVersionCodes.S_V2)
{
    if (CheckSelfPermission(Manifest.Permission.WakeLock) != Permission.Granted)
    {
        RequestPermissions(new[] { Manifest.Permission.WakeLock }, requestWakeId);
    }
}

5. 切换到FCM V1 API(替代Legacy API)

Legacy API已逐步弃用,改用V1 API并设置高优先级:

{
    "message": {
        "token": "你的设备最新Token",
        "data": {
            "body": "测试消息内容",
            "title": "测试标题"
        },
        "android": {
            "priority": "high"
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:42:03