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

Android接收OneSignal呼叫通知时播放45秒铃声的实现方案

OneSignal呼叫通知播放铃声方案及替代实现

OneSignal原生支持情况

  • OneSignal本身不直接提供持续播放自定义时长铃声的功能,它的通知声音是系统级短提示音,依赖系统通知渠道的声音设置,无法控制播放时长到45秒这类自定义需求。
  • 但可以通过OneSignal的通知接收回调触发自定义铃声播放逻辑,这是实现需求的核心路径。

自定义铃声播放实现(Android端)

1. 监听OneSignal通知接收事件

在应用中注册通知接收监听器,识别呼叫通知后启动音频播放:

OneSignal.setNotificationWillShowInForegroundHandler(new NotificationWillShowInForegroundHandler() {
    @Override
    public void notificationWillShowInForeground(OSNotificationReceivedEvent event) {
        // 通过自定义字段判断是否为呼叫通知
        if ("call_notification".equals(event.getNotification().getAdditionalData().optString("type"))) {
            startCallRingtone();
        }
        event.complete(event.getNotification());
    }
});

2. 实现45秒时长的铃声播放

提供两种原生实现方案:

方案一:MediaPlayer(自定义铃声文件)

private MediaPlayer mediaPlayer;

private void startCallRingtone() {
    try {
        // 从raw资源加载铃声文件
        mediaPlayer = MediaPlayer.create(this, R.raw.call_ringtone);
        mediaPlayer.setLooping(false);
        mediaPlayer.start();
        
        // 45秒后自动停止
        new Handler(Looper.getMainLooper()).postDelayed(() -> {
            if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
                mediaPlayer.release();
                mediaPlayer = null;
            }
        }, 45000);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

注意:需在接听/拒接按钮的点击事件中同步停止铃声播放。

方案二:RingtoneManager(系统来电铃声)

如果想用系统默认铃声:

private Ringtone callRingtone;

private void startCallRingtone() {
    Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
    callRingtone = RingtoneManager.getRingtone(this, ringtoneUri);
    callRingtone.play();
    
    // 45秒后自动停止
    new Handler(Looper.getMainLooper()).postDelayed(() -> {
        if (callRingtone != null && callRingtone.isPlaying()) {
            callRingtone.stop();
        }
    }, 45000);
}

iOS端实现思路

通过OneSignal的通知回调触发音频播放,使用AVAudioPlayer实现自定义时长逻辑:

import AVFoundation

var audioPlayer: AVAudioPlayer?

func notificationWillDisplay(_ notification: OSNotification, with completionHandler: @escaping (OSNotificationDisplayType) -> Void) {
    if let type = notification.additionalData?["type"] as? String, type == "call_notification" {
        startCallRingtone()
    }
    completionHandler(.show)
}

func startCallRingtone() {
    guard let url = Bundle.main.url(forResource: "call_ringtone", withExtension: "mp3") else { return }
    do {
        audioPlayer = try AVAudioPlayer(contentsOf: url)
        audioPlayer?.play()
        
        // 45秒后自动停止
        DispatchQueue.main.asyncAfter(deadline: .now() + 45) {
            if self.audioPlayer?.isPlaying == true {
                self.audioPlayer?.stop()
                self.audioPlayer = nil
            }
        }
    } catch {
        print(error.localizedDescription)
    }
}

注意:iOS需在Info.plist中添加UIBackgroundModes并包含audio,开启音频后台权限。

关键注意事项

  • 权限:Android需确保应用拥有音频播放权限(使用资源文件无需额外权限,加载外部文件需READ_EXTERNAL_STORAGE);iOS需开启音频后台权限。
  • 交互同步:用户点击接听/拒接时,必须立即停止铃声播放,避免异常体验。
  • 资源释放:播放结束或停止后,及时释放MediaPlayer/AVAudioPlayer资源,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:31:04