安卓推送通知自定义音效无法使用(FCM)

7
我已经使用FCM从云函数成功发送推送通知。这对iOS和Android都有效,可以在iOS上显示适当的图标并播放自定义声音。 除了Android的自定义声音外,一切正常,它只会播放默认声音。 我创建了一个文件夹,并按如下方式添加了我的声音文件:android\app\src\main\res\raw\mp3_example.mp3 这个mp3文件长度为27秒。我还尝试过.wav和.aiff文件。
我读到可能需要为Android的后续版本创建推送通知通道,因此问题可能与此有关。我尝试创建一个通道并使用云函数中的channelID,它可以工作,但没有声音,只有振动。
测试设备是运行Android 8的Moto G6。 我正在使用: FCM Firebase Cloud Functions Ionic 4 Capacitor https://github.com/stewwan/capacitor-fcm 云函数:
const notification: admin.messaging.Notification = {
      title: title,
      body: body
  }

  const message: admin.messaging.Message = {
    notification,
    topic: 'QMTBC',
    android:{
      notification:{
        sound: 'mp3_example.mp3',
        icon: 'push_logo',
        color: '#000000'
      }
    },
    apns:{
        payload:{
          aps: {
            sound: 'gears-short.wav'
          }
        }
    }
  }

  return admin.messaging().send(message)

app.component.ts

import { FCM } from 'capacitor-fcm';

const fcm = new FCM();
const { PushNotifications } = Plugins;

initializeApp() {
    this.platform.ready().then(() => {

      PushNotifications.register();

      PushNotifications.addListener('registration', (token: PushNotificationToken) => {
        console.log('token ' + token.value);
        fcm
        .subscribeTo({ topic: 'QMTBC' })
        .then(r => console.log(`subscribed to topic`))
        .catch(err => console.log(err));        
      });

      PushNotifications.addListener('registrationError', (error: any) => {
        console.log('error on register ' + JSON.stringify(error));
      });

      PushNotifications.addListener('pushNotificationReceived', (notification: PushNotification) => {
        console.log('notification ' + JSON.stringify(notification));
        this.pushNotificationService.notifications.push(notification);
      });

      PushNotifications.addListener('pushNotificationActionPerformed', (notification: PushNotificationActionPerformed) => {
        console.log('notification ' + JSON.stringify(notification));
        this.pushNotificationService.notifications.push(notification);
      });

      fcm.getToken()
        .then(r => console.log(`Token ${r.token}`))
        .catch(err => console.log(err));
    });
  }

更新:

我尝试按照以下方式创建通道。 如果我使用这个通道,我只会得到默认的声音。如果我不指定任何通道或指定一个不存在的通道,则也会得到默认的声音(默认通道)。

云函数:

const message: admin.messaging.Message = {
    notification,
    topic: 'QMTBC',
    android:{
      notification:{
        sound: 'punch.mp3',
        icon: 'push_logo',
        color: '#000000',
        channelId: 'QMTBC'
      }
    }

app.component.ts

const channel: PushNotificationChannel = {
          description: 'QMTBC',
          id : 'QMTBC',
          importance: 5,
          name : 'QMTBC'
        };

        PushNotifications.createChannel(channel).then(channelResult => {
          console.log(channelResult);
          console.log('Channel created');
          // PushNotifications.listChannels().then(channels => {
          //   console.log('Channels');
          //   console.log(channels);
          // });
        }, err => {
          console.log('Error Creating channel');
          console.log(err);
        });
      });

更新2:

我可以在我的设备上看到为这个应用程序创建的通道,它显示声音是默认的。我可以手动将其更改为Android内置的其他声音,并且可以正常工作。但我仍然无法使用自定义声音。

更新3:

只有在Android版本 < 8上,自定义声音才能正常工作。这只是在模拟器上测试过。


你找到发送通知并使用自定义声音播放的解决方案了吗?我把文件放在res/raw目录下,但它们无法播放。 - Kash
我有同样的问题,在安卓8之后设置自定义声音无法工作。 - Tim Wong
@fpsColton 有趣。所以你是说声音是设置在通道上而不是通知本身?下次我在这个项目上工作时,我会尝试一下,但是如果有其他人尝试了,请告诉我结果。 - MadMac
我也遇到了同样的问题..有人解决了吗? - Wolfetto
1
是的,@MadMac,声音是在你定义通道时设置的,而不是在你发送通知时设置的。 - fpsColton
显示剩余2条评论
3个回答

5

@MadMac 这几天我也遇到了同样的问题,阅读了 FCM 文档和 Capacitor Java 代码后,我解决了它。

需要将可见性设为1,将文件放置在 res/raw 文件夹中。

PushNotifications.createChannel({
            description: 'General Notifications',
            id: 'fcm_default_channel',
            importance: 5,
            lights: true,
            name: 'My notification channel',
            sound: 'notifications.wav',
            vibration: true,
            visibility: 1
        }).then(()=>{
            console.log('push channel created: ');
        }).catch(error =>{
            console.error('push channel error: ', error);
        });

我在我的Firestore函数中使用这个有效载荷来发送通知。

{
            android: {
                notification: {
                    defaultSound: true,
                    notificationCount: 1,
                    sound: 'notifications.wav',
                    channelId: 'fcm_default_channel'
                },
                ttl: 20000,
                collapseKey
            },
            apns: {
                payload: {
                    aps: {
                        badge: 1,
                        sound: 'default'
                    }
                }
            },
            notification: {
                title,
                body: message,
            },
            token: token
        };

defaultSound: true? - genericUser
1
是的@genericUser,您可以在XML配置中指定默认声音。 来自FCM的文档: /**
  • 如果设置为“true”,则使用Android框架的默认通知声音。
  • 默认值在config.xml中指定。 */ defaultSound?:布尔值;
- ThonyFD

1
这是一个非常好的问题,帮助我找到了答案。所以我在这里发布我的答案。尝试在创建通知渠道时将通知的声音设置为通知渠道本身。根据您提供的信息,我认为旧版的Android将根据通知负载中的声音字段播放声音,但在新版本中,您需要直接将其设置为通知渠道本身,因为谷歌现在打算控制它。我不得不卸载并重新安装应用程序以使此代码更改生效,因为我的通道先前已初始化,并且通道在第一次初始化后不会更新。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !notificationChannelsInitialized) {
            val newMessagesChannel = NotificationChannel(NEW_MESSAGES_NOTIFICATION_CHANNEL_ID, "New Messages", NotificationManager.IMPORTANCE_HIGH)

            val notificationSoundUri =
                Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE.toString() + "://" + context.packageName + "/" + R.raw.ns) // ns.wav is my notification sound file in the res/raw folder in Android Studio
            val notificationSoundUriAttributes = AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build()
            newMessagesChannel.setSound(notificationSoundUri, notificationSoundUriAttributes)

            val notificationManager: NotificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannels(listOf( newMessagesChannel)) // and other channels
        }

谢谢。下个月我更新项目时会尝试一下。 - MadMac

0

我使用react-native-push-notification库(这里)使其在React Native上运行。解决的关键是您必须在应用程序内部创建一个通道(我曾认为通道是在后端创建的,但那不对)。在将mp3文件放置在我的应用程序的android文件夹中的res/raw目录中之后,我在React Native中添加了以下代码(从上述库的文档中复制),然后它就可以工作了:

import PushNotification, {Importance} from 'react-native-push-notification';
...
  PushNotification.createChannel(
    {
      channelId: "channel-id", // (required)
      channelName: "My channel", // (required)
      channelDescription: "A channel to categorise your notifications", // (optional) default: undefined.
      playSound: true, // (optional) default: true
      soundName: "mp3_example", // (optional) See `soundName` parameter of `localNotification` function
      importance: Importance.HIGH, // (optional) default: Importance.HIGH. Int value of the Android notification importance
      vibrate: true, // (optional) default: true. Creates the default vibration pattern if true.
    },
    (created) => console.log(`createChannel returned '${created}'`) // (optional) callback returns whether the channel was created, false means it already existed.
  );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接