点击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
相关产品推荐
相关产品推荐

