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

点击FCM推送通知跳转浏览器打开指定URL功能失效求助

问题核心原因
  • FCM消息分为两类:通知消息 和 数据消息,在FCM控制台发送的默认是通知消息,当APP退到后台时,这类消息不会触发onMessageReceived回调,直接由系统弹出默认通知,点击默认启动APP首页,不会执行自定义跳转逻辑
  • 当前代码缺少两个必要逻辑:一是自定义通知的构建和弹出,二是跳转Intent的必要flag设置,Service中启动Activity必须添加FLAG_ACTIVITY_NEW_TASK标记否则会抛出异常
  • 没有给通知设置点击PendingIntent,系统默认通知的点击事件和编写的browserIntent没有关联

正确实现步骤

1. 调整FCM消息发送类型

如果要全场景覆盖(前台/后台/杀死状态都能触发自定义逻辑),建议在FCM控制台发送数据消息或者混合类型消息,不要只发纯通知消息。如果用控制台发送,可在「其他选项」里添加自定义键值对,比如key填url,value填需要跳转的目标链接。

2. 完善FMMessagingService代码

收到消息后先构建自定义通知,给通知设置带跳转逻辑的PendingIntent,再弹出通知:

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;

import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class FMMessagingService extends FirebaseMessagingService {
    private static final String CHANNEL_ID = "fcm_notification_channel";
    private static final int NOTIFICATION_ID = 1001;

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        
        // 1. 获取要跳转的url,优先取自定义数据里的url,也可写死固定链接
        String targetUrl = "http://www.google.com";
        if (remoteMessage.getData().containsKey("url")) {
            targetUrl = remoteMessage.getData().get("url");
        }

        // 2. 创建跳转浏览器的Intent
        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(targetUrl));
        browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        
        // 3. 创建PendingIntent,绑定通知点击事件
        PendingIntent pendingIntent;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            pendingIntent = PendingIntent.getActivity(this, 0, browserIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
        } else {
            pendingIntent = PendingIntent.getActivity(this, 0, browserIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }

        // 4. 创建通知渠道(Android 8.0及以上强制要求)
        createNotificationChannel();

        // 5. 构建自定义通知
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
                // 注意:此处需要替换为你自己应用的通知图标
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(remoteMessage.getNotification() != null ? remoteMessage.getNotification().getTitle() : "新通知")
                .setContentText(remoteMessage.getNotification() != null ? remoteMessage.getNotification().getBody() : "点击查看详情")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setContentIntent(pendingIntent)
                // 点击通知后自动消失
                .setAutoCancel(true);

        // 6. 弹出通知
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        notificationManager.notify(NOTIFICATION_ID, builder.build());
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = "推送通知";
            String description = "接收应用推送消息";
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
        // 此处可处理FCM token更新的逻辑,可选
    }
}

3. 补充AndroidManifest.xml配置

添加必要权限,同时注册自定义的消息服务:

<!-- 网络权限(FCM运行必需) -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Android 13及以上通知权限,必需 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<application ...>
    <!-- 注册FCM消息服务 -->
    <service
        android:name=".FMMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
</application>

4. 后台/杀死状态兼容处理

如果需要APP在后台或者被杀死时点击通知也能跳转,需要在主Activity的onCreate和onNewIntent方法中处理通知携带的参数:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    // 处理APP被杀死时点击通知唤起的场景
    if (getIntent().getExtras() != null) {
        if (getIntent().hasExtra("url")) {
            String url = getIntent().getStringExtra("url");
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(browserIntent);
            // 跳转后可关闭当前Activity,避免停留在APP首页
            finish();
        }
    }
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    // 处理APP在后台时点击通知唤起的场景
    if (intent.getExtras() != null && intent.hasExtra("url")) {
        String url = intent.getStringExtra("url");
        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(browserIntent);
        finish();
    }
}

测试注意事项
  • 确保项目已经正确集成Firebase配置,google-services.json文件已经放到项目根目录
  • Android 13及以上设备需要主动申请POST_NOTIFICATIONS权限,用户授权后才会弹出通知
  • 测试时建议发送带自定义url字段的数据消息,避免纯通知消息的默认逻辑干扰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:27:03