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

如何在Xamarin iOS中实现指定时间本地通知触发时播放闹铃音效

Xamarin iOS 本地通知触发闹铃音效及dismiss时自动停止实现方案

实现核心说明

不要使用iOS系统自带的通知音效,系统管控的通知音效无法通过应用代码手动停止,必须自行通过AVAudioPlayer实现音效的播放和停止控制。


1. 前置配置

  • 在Info.plist中添加必要权限:
    • 通知权限:添加键NSUserNotificationUsageDescription,值自定义为「需要获取通知权限以推送闹铃提醒」
    • 后台音频权限(支持应用后台/被杀死时仍能播放音效):添加键UIBackgroundModes,类型为数组,包含值audio
  • 引入依赖命名空间:
using UserNotifications;
using AVFoundation;
using Foundation;

2. 全局音效管理器实现

定义全局单例类管理音频播放器,避免播放器被GC回收导致播放中断:

public static class AudioPlayerManager
{
    private static AVAudioPlayer _audioPlayer;

    // 初始化音频播放器,参数为闹铃音效文件的本地路径
    public static void Init(string audioFilePath)
    {
        // 配置音频会话为播放模式,支持后台播放
        var session = AVAudioSession.SharedInstance();
        session.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.MixWithOthers);
        session.SetActive(true);

        var audioUrl = NSUrl.FromFilename(audioFilePath);
        _audioPlayer = AVAudioPlayer.FromUrl(audioUrl);
        _audioPlayer.NumberOfLoops = -1; // 设置为无限循环播放,直到手动停止
        _audioPlayer.PrepareToPlay();
    }

    // 播放闹铃
    public static void PlayAlarm()
    {
        _audioPlayer?.Play();
    }

    // 停止闹铃
    public static void StopAlarm()
    {
        if (_audioPlayer != null && _audioPlayer.Playing)
        {
            _audioPlayer.Stop();
            _audioPlayer.CurrentTime = 0; // 重置播放进度到开头
        }
    }
}

3. AppDelegate 初始化配置

在FinishedLaunching方法中申请通知权限、注册通知代理、初始化音效管理器:

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
    // 申请通知权限
    UNUserNotificationCenter.Current.RequestAuthorization(
        UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge, 
        (granted, error) => 
        {
            if (granted)
            {
                // 绑定自定义通知代理
                UNUserNotificationCenter.Current.Delegate = new CustomNotificationDelegate();
            }
        });

    // 初始化音效管理器,将闹铃文件放入iOS项目Resources目录,生成操作设置为BundleResource
    var alarmPath = NSBundle.MainBundle.PathForResource("你的闹铃文件名", "mp3");
    AudioPlayerManager.Init(alarmPath);

    return base.FinishedLaunching(application, launchOptions);
}

4. 本地通知发送逻辑

// 调用示例:在需要触发闹铃的位置调用该方法发送通知
public void ScheduleAlarmNotification(DateTime alarmTime, string title, string content)
{
    var notificationContent = new UNMutableNotificationContent
    {
        Title = title,
        Body = content,
        CategoryIdentifier = "ALARM_NOTIFICATION"
        // 注意:不要设置Sound属性,我们自行控制音效播放
    };

    // 配置通知触发时间
    var triggerDate = alarmTime.AddSeconds(-1); // 提前1秒触发,对齐音效播放时间
    var trigger = UNCalendarNotificationTrigger.CreateTrigger(triggerDate, false);

    // 发送通知请求
    var requestId = Guid.NewGuid().ToString();
    var request = UNNotificationRequest.FromIdentifier(requestId, notificationContent, trigger);
    UNUserNotificationCenter.Current.AddNotificationRequest(request, null);

    // 同步安排闹铃播放任务,和通知触发时间对齐
    var delay = (long)(alarmTime - DateTime.Now).TotalMilliseconds * 1000000;
    DispatchQueue.MainQueue.DispatchAfter(new DispatchTime(DispatchTime.Now, delay), () =>
    {
        AudioPlayerManager.PlayAlarm();
    });
}

5. 自定义通知代理,监听dismiss事件

实现UNUserNotificationCenterDelegate,监听用户对通知的操作,用户dismiss通知时自动停止音效:

public class CustomNotificationDelegate : UNUserNotificationCenterDelegate
{
    // 应用在前台时收到通知的回调
    public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
    {
        // 前台展示通知弹窗
        completionHandler(UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Badge);
        // 播放闹铃
        AudioPlayerManager.PlayAlarm();
    }

    // 用户对通知执行操作(点击、dismiss)的回调
    public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
    {
        // 用户dismiss通知时停止闹铃
        if (response.ActionIdentifier == UNNotificationAction.DismissActionIdentifier)
        {
            AudioPlayerManager.StopAlarm();
        }
        // 用户点击通知进入应用时也停止闹铃
        else if (response.ActionIdentifier == UNNotificationAction.DefaultActionIdentifier)
        {
            AudioPlayerManager.StopAlarm();
            // 此处可添加跳转应用内对应页面的逻辑
        }
        completionHandler();
    }
}

注意事项

  • 闹铃音频文件必须放入iOS项目的Resources目录,且将文件的生成操作设置为BundleResource,否则会找不到文件
  • 应用被杀死状态下用户操作通知时,系统会自动唤醒应用执行DidReceiveNotificationResponse中的停止逻辑,无需额外处理
  • iOS 15+对后台运行权限限制更严格,若出现后台无法播放音效的问题,请检查UIBackgroundModes配置是否正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:45:03