Flutter应用配置后端触发的后台通知自定义铃声问题求助
自定义推送通知铃声实现方案
一、先修正基础配置问题
你当前本地铃声文件是alarm.mp3,但后端推送的notification.sound字段写的是alert.mp3,文件名不匹配是首要问题。需把后端的sound值改成不带后缀的文件名(即alarm),修正后的后端JSON如下:
{ "to" : "my_device_token", "collapse_key" : "type_a", "priority" : "high", "notification" : { "body" : "Test Notification body for custom sound {{datestamp}}", "title": "Custom sound alert", "sound": "alarm" } }
二、后台通知(应用在后台/进程被杀)自定义铃声
当应用处于后台或进程被杀时,通知由系统直接处理,只需做好两点:
- 确保铃声文件放在
res/raw目录下,文件名全小写(不能包含大写或特殊字符),比如alarm.mp3 - 后端推送的
notification.sound字段值为不带后缀的文件名,同时保持priority为high(你已设置,无需修改)
三、前台通知(应用在前台)自定义铃声
应用在前台时,系统不会自动播放自定义铃声,需在FirebaseMessagingService的onMessageReceived方法中手动构建通知并设置铃声:
- 初始化通知渠道(Android O及以上必须),建议在应用启动时执行:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channelId = "custom_sound_channel" val channelName = "Custom Sound Notifications" val channelDescription = "Notifications with custom ringtone" val importance = NotificationManager.IMPORTANCE_HIGH val channel = NotificationChannel(channelId, channelName, importance).apply { description = channelDescription // 绑定自定义铃声 val soundUri = Uri.parse("android.resource://${packageName}/${R.raw.alarm}") setSound(soundUri, AudioAttributes.DEFAULT_NOTIFICATION) } val notificationManager = getSystemService(NotificationManager::class.java) notificationManager.createNotificationChannel(channel) }
- 在
onMessageReceived中构建并发送通知:
override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) // 判断应用是否在前台(可根据需求调整逻辑) if (isAppInForeground()) { val channelId = "custom_sound_channel" val notificationBuilder = NotificationCompat.Builder(this, channelId) .setContentTitle(remoteMessage.notification?.title) .setContentText(remoteMessage.notification?.body) .setSmallIcon(R.drawable.ic_notification) .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置自定义铃声 .setSound(Uri.parse("android.resource://${packageName}/${R.raw.alarm}")) val notificationManager = NotificationManagerCompat.from(this) notificationManager.notify(1, notificationBuilder.build()) } }
- 辅助方法判断应用是否在前台:
private fun isAppInForeground(): Boolean { val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val appProcesses = activityManager.runningAppProcesses ?: return false for (appProcess in appProcesses) { if (appProcess.processName == packageName && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { return true } } return false }
额外注意事项
- 铃声文件推荐使用MP3或WAV格式,文件大小不宜过大,避免加载延迟
- Android 12及以上版本,通知渠道的
importance必须设为IMPORTANCE_HIGH才能播放铃声 - 若使用非Firebase的推送服务,核心逻辑一致:后台依赖推送字段匹配本地文件,前台需手动构建通知并绑定铃声
内容的提问来源于stack exchange,提问作者Shehzad Ahmad
相关产品推荐
相关产品推荐

