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

iOS端Maui健身应用后台运行及音频播放问题求助

健身App iOS后台运行问题修复方案

问题场景

健身App核心需求:

  • 启动后追踪训练总时长
  • 用户完成一组动作后启动休息倒计时(如30秒),结束时播放提示音提醒开始下一组

Android端运行正常,但iOS端切换到其他App(如音乐、Facebook)时,App会被系统终止,导致训练需重新开始。尝试实现iOS后台任务后,倒计时能完成但无提示音,且倒计时结束后App仍会终止。

现有代码

音效播放与倒计时逻辑

private async Task playSoundAsync()
{              
     var file = await FileSystem.OpenAppPackageFileAsync("finalbeepsound.mp3");
     player = audioManager.CreatePlayer(file);
     await Task.Run( () =>  player.Play());
}


public void StartRestTimer()
{              
    Debug.WriteLine("Start Rest Timer hit.");   
    if (Set.Rest != 0)              
    {                 
        IsCountDownShowing = true;                 
        IsSaveButtonShowing = false;                   
        IsCountingDown = true;                 
        SecondsRemaining = Set.Rest;                 
        timer = Application.Current.Dispatcher.CreateTimer();                 
        timer.Interval = TimeSpan.FromSeconds(1);                 
        timer.Tick += async (sender, args) =>                 
        {                      
               SecondsRemaining--;                       
               if (SecondsRemaining == 0)                      
               {                          
                   IsCountingDown = false;                          
                   IsCountDownShowing = false;                          
                   IsSaveButtonShowing = true;                          
                   await playSoundAsync();                          
                   timer.Stop();                      
               }              };                 
               timer.Start();              
      }                     
}

iOS AppDelegate代码

using Foundation;
using UIKit;
namespace PumpPal; 

[Register("AppDelegate")] 
public class AppDelegate : MauiUIApplicationDelegate { 
    nint taskID;    
    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();       

    public override void OnActivated(UIApplication application)     {         
        Console.WriteLine("On Activated called, App is active."); 
             
    }       

    public override void WillEnterForeground(UIApplication application)     {   
        Console.WriteLine("App will enter foreground");               
        UIApplication.SharedApplication.EndBackgroundTask(taskID);   
    }       

    public override void OnResignActivation(UIApplication application)     {                    
        Console.WriteLine("OnResignActivation called, App moving to inactive state."); 
        taskID = UIApplication.SharedApplication.BeginBackgroundTask(() => { });
    }      

    public override void DidEnterBackground(UIApplication application)     {         
        Console.WriteLine("App entering background state.");     
    }       
    public override void WillTerminate(UIApplication application)     {         
        Console.WriteLine("App is terminating");     
    }
}

修复方案

1. 配置iOS后台权限

iOS对后台行为管控严格,需在Platforms/iOS/Info.plist中添加后台模式权限:

<key>UIBackgroundModes</key>
<array>
    <string>audio</string> <!-- 允许后台播放音频 -->
    <string>fetch</string> <!-- 支持后台任务 -->
</array>

2. 修复后台任务生命周期管理

调整AppDelegate中后台任务的创建与结束时机,避免被系统判定为无效任务:

public override void DidEnterBackground(UIApplication application)
{
    Console.WriteLine("App entering background state.");
    // 创建后台任务并设置超时回调
    taskID = UIApplication.SharedApplication.BeginBackgroundTask(() =>
    {
        UIApplication.SharedApplication.EndBackgroundTask(taskID);
        taskID = nint.MinValue;
    });

    // 后台执行核心逻辑
    Task.Run(async () =>
    {
        // 这里可放置需要持续运行的计时/追踪逻辑
        await Task.Delay(TimeSpan.FromSeconds(Set.Rest));
        // 任务完成后主动结束后台任务
        UIApplication.SharedApplication.EndBackgroundTask(taskID);
        taskID = nint.MinValue;
    });
}

public override void WillEnterForeground(UIApplication application)
{
    Console.WriteLine("App will enter foreground");
    if (taskID != nint.MinValue)
    {
        UIApplication.SharedApplication.EndBackgroundTask(taskID);
        taskID = nint.MinValue;
    }
}

3. 修复后台音效播放

激活iOS音频会话以支持后台播放:

private async Task playSoundAsync()
{
    // 激活音频会话,允许后台播放
    var audioSession = AVAudioSession.SharedInstance();
    await audioSession.SetCategoryAsync(AVAudioSessionCategory.Playback);
    await audioSession.SetActiveAsync(true);

    var file = await FileSystem.OpenAppPackageFileAsync("finalbeepsound.mp3");
    player = audioManager.CreatePlayer(file);
    player.FinishedPlaying += (s, e) =>
    {
        // 播放结束后关闭音频会话
        audioSession.SetActiveAsync(false);
    };
    player.Play();
}

4. 替换UI依赖型计时器

DispatcherTimer依赖UI线程,后台时易失效,改用Task.Delay实现后台兼容的倒计时:

public void StartRestTimer()
{
    Debug.WriteLine("Start Rest Timer hit.");
    if (Set.Rest != 0)
    {
        IsCountDownShowing = true;
        IsSaveButtonShowing = false;
        IsCountingDown = true;
        SecondsRemaining = Set.Rest;

        Task.Run(async () =>
        {
            while (SecondsRemaining > 0 && IsCountingDown)
            {
                await Task.Delay(TimeSpan.FromSeconds(1));
                // 更新UI需回到主线程
                MainThread.BeginInvokeOnMainThread(() => SecondsRemaining--);
            }

            if (SecondsRemaining == 0)
            {
                MainThread.BeginInvokeOnMainThread(() =>
                {
                    IsCountingDown = false;
                    IsCountDownShowing = false;
                    IsSaveButtonShowing = true;
                });
                await playSoundAsync();
            }
        });
    }
}

内容的提问来源于stack exchange,提问作者Justin Sinnard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:57:05