You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

安卓应用后台发送消息及Firebase推送退后台接收问题咨询

安卓后台消息发送与Firebase推送后台接收问题解决方案

嘿,我来帮你搞定这两个安卓开发的问题!

一、如何在安卓应用后台发送消息?

安卓系统对后台任务的限制越来越严格(尤其是Android 8.0及以上),普通Service很容易被系统回收,所以得选合适的方案:

  • 即时消息发送:推荐用WorkManager来调度一次性任务,它会自动适配系统版本,保证任务能执行:
    1. 写一个继承自Worker的类,在doWork()方法里实现消息发送的逻辑(比如调用API发消息)
    2. 构建OneTimeWorkRequest,然后通过WorkManager.getInstance(context).enqueue(request)来启动任务
  • 定时/周期性消息发送:用PeriodicWorkRequest,注意系统要求最短间隔不能少于15分钟
  • 发送本地通知:不管前台后台,只要有POST_NOTIFICATIONS权限(Android 13+需要),直接调用NotificationManager就能发送,不需要额外的后台服务

二、Firebase推送后台接收异常的解决方案

你提到前台接收正常,后台不行,还考虑用IntentService——其实IntentService在Android 8.0之后后台启动会被系统限制,Firebase官方推荐用FirebaseMessagingService来处理推送,这才是正确的姿势,我给你一步步说:

1. 正确配置FirebaseMessagingService

首先在AndroidManifest.xml里注册服务:

<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

2. 实现自定义的FirebaseMessagingService

重写onMessageReceived()方法,这里可以处理两种推送消息:

  • 数据消息:不管应用在前台还是后台,只要没被完全杀死,都会触发这个方法,适合自定义处理
  • 通知消息:后台时系统会自动显示通知,前台时才会走到这个方法

给你补全你的服务类代码:

package com.example.kai.msgtest;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import androidx.core.app.NotificationCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // 处理数据消息(后台也会触发)
        if (!remoteMessage.getData().isEmpty()) {
            String title = remoteMessage.getData().get("title");
            String body = remoteMessage.getData().get("body");
            sendCustomNotification(title, body);
        }

        // 处理通知消息(前台时自定义显示,后台系统自动处理)
        if (remoteMessage.getNotification() != null) {
            String title = remoteMessage.getNotification().getTitle();
            String body = remoteMessage.getNotification().getBody();
            if (isAppInForeground()) {
                sendCustomNotification(title, body);
            }
        }
    }

    // 发送自定义通知
    private void sendCustomNotification(String title, String body) {
        String channelId = "msgtest_default_channel";
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // Android O及以上需要创建通知渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    channelId,
                    "消息通知渠道",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            notificationManager.createNotificationChannel(channel);
        }

        Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
                .setSmallIcon(R.drawable.ic_notification) // 替换成你的应用图标
                .setContentTitle(title)
                .setContentText(body)
                .setAutoCancel(true)
                .setSound(defaultSound);

        notificationManager.notify(1001, builder.build());
    }

    // 判断应用是否在前台
    private boolean isAppInForeground() {
        // 这里可以用ActivityManager来判断,示例代码:
        /*
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
        if (runningProcesses != null) {
            for (ActivityManager.RunningAppProcessInfo process : runningProcesses) {
                if (process.processName.equals(getPackageName()) 
                    && process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    return true;
                }
            }
        }
        return false;
        */
        return false; // 替换成实际的判断逻辑
    }
}

3. 关键注意事项

  • 别再用IntentService处理推送了!它在后台启动会被系统拦截,FirebaseMessagingService是专门为推送设计的,系统会在收到推送时唤醒它
  • 很多厂商的定制系统(比如小米、华为)会把后台应用加入电池优化,导致推送收不到——一定要引导用户把你的应用加入电池优化白名单
  • 如果用Firebase控制台发送通知,后台时系统会自动显示,如果你想自己处理后台推送,要发送数据消息(在控制台的「高级选项」里选择数据消息,或者用API发送data字段)

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

火山引擎 最新活动