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

Xamarin.Forms接入OneSignal后后台收推送无法播放来电铃声求助

Xamarin.Forms基于OneSignal实现推送后台无法播放铃声问题

我正在基于Xamarin.Forms开发原型,使用OneSignal库实现向安装了同款应用的其他设备发送推送通知的功能,当前应用无论处于前台还是后台都能正常接收推送。我在HandleNotificationReceived回调中捕获推送后调用自定义服务播放来电铃声,应用处于前台时功能完全正常,但退至后台后收到推送仅能弹出通知,铃声无法播放。我了解应用后台运行存在相关限制,推测问题与此有关,附相关业务代码。


相关代码

应用全局代码

namespace SaferProject
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            var page = new NavigationPage(new Views.MainMenu());
            MainPage = page;

            IPlaySoundService playSoundService;
            playSoundService = DependencyService.Get<IPlaySoundService>();

            OneSignal.Current.SetLogLevel(LOG_LEVEL.VERBOSE, LOG_LEVEL.NONE);
            OneSignal.Current.StartInit("417d7b75-ed42-4ca5-aed3-42612d260235")
            .Settings(new Dictionary<string, bool>() {
                { IOSSettings.kOSSettingsKeyAutoPrompt, false },
                { IOSSettings.kOSSettingsKeyInAppLaunchURL, false } })
            .InFocusDisplaying(OSInFocusDisplayOption.Notification)
             .HandleNotificationOpened((result) =>
             {
                 if (playSoundService.GetServiceStatus())
                 {
                     playSoundService.StopSystemSound();
                 }
                 Debug.WriteLine("HandleNotificationOpened: {0}", result.notification.payload.body);
             })
             .HandleNotificationReceived((notification) =>
             {
                 playSoundService.PlaySystemSound();
                 DeviceDisplay.KeepScreenOn = true;
                 Debug.WriteLine("HandleNotificationReceived: {0}", notification.payload.body);
             })
             .HandleInAppMessageClicked((action) =>
             {
                 // IAM元素点击处理示例
                 Debug.WriteLine("HandledInAppMessageClicked: {0}", action.clickName);
             })
            .EndInit();

            OneSignal.Current.RegisterForPushNotifications();
        }

        protected override void OnStart()
        {
            IPlaySoundService playSoundService;
            playSoundService = DependencyService.Get<IPlaySoundService>();
            if (playSoundService.GetServiceStatus())
            {
                playSoundService.StopSystemSound();
            }

            //处理应用进入休眠逻辑
            Task.Run(async () => { await SaferProjectService.GetInstance().GetOut(UserManager.GetLogUser()); });
        }

        protected override void OnSleep()
        {
            //处理应用进入休眠逻辑
            Task.Run(async()=> { await SaferProjectService.GetInstance().GetOut(UserManager.GetLogUser()); });
        }

        protected override void OnResume()
        {
            //处理应用恢复逻辑
            Task.Run(async () => { await SaferProjectService.GetInstance().GetIn(UserManager.GetLogUser()); });
        }
    }
}

音频服务接口定义

namespace SaferProject.Services
    {
        public interface IPlaySoundService
        {
            Task PlaySystemSound();
            Task StopSystemSound();
            void SetServiceStatus(bool isPlaying);
            bool GetServiceStatus();
        }
    }

Android端音频服务实现

[assembly: Xamarin.Forms.Dependency(typeof(PlaySoundService))]
namespace SaferProject.Droid.Services
{
    [Activity(Label = "PlaySoundService", NoHistory = true, Theme = "@style/MyTheme", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class PlaySoundService : IPlaySoundService
    {
        private static PlaySoundService _instance;
        readonly Ringtone _rt;
        bool IsPlaying;

        public static PlaySoundService GetInstance()
        {
            if (_instance == null)
            {
                _instance = new PlaySoundService();
            }
            return _instance;
        }

        public PlaySoundService()
        {
            AudioManager am = (AudioManager)Application.Context.GetSystemService(Context.AudioService);
            if (!am.RingerMode.Equals(2))
            {
                am.RingerMode = RingerMode.Normal;
            }

            Android.Net.Uri uri = RingtoneManager.GetDefaultUri(RingtoneType.Ringtone);
            _rt = RingtoneManager.GetRingtone(MainActivity.instance.ApplicationContext, uri);
        }

        public Task PlaySystemSound()
        {
            _rt.Play();
            Vibration.Vibrate(500);
            SetServiceStatus(true);

            return Task.CompletedTask;
        }

        public Task StopSystemSound()
        {
            Vibration.Cancel();
            _rt.Stop();
            SetServiceStatus(false);

            return Task.CompletedTask;
        }

        public void SetServiceStatus(bool isPlaying)
        {
            IsPlaying = isPlaying;
        }

        public bool GetServiceStatus()
        {
            return IsPlaying;
        }
    }
}

Android主活动代码

namespace SaferProject.Droid
{
    [Activity(Label = "SaferProject.Droid", Theme = "@style/MainTheme", MainLauncher = false,
        ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
        ScreenOrientation = ScreenOrientation.Portrait, LaunchMode = LaunchMode.SingleTop)] //用于控制屏幕方向
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        public static MainActivity instance { set; get; }
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            instance = this;

            // Radio Button配置
            Xamarin.Forms.Forms.SetFlags(new string[] { "RadioButton_Experimental" });

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());

            OneSignal.Current.SetLogLevel(LOG_LEVEL.VERBOSE, LOG_LEVEL.NONE);

            OneSignal.Current.StartInit("417d7b75-ed42-4ca5-aed3-42612d260235")
             .InFocusDisplaying(OSInFocusDisplayOption.Notification)
             .EndInit();
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

Android清单配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="6" android:versionName="1.2.0" package="br.com.safertechnology.saferproject" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="30" />
    <permission android:name="$br.com.safertechnology.saferproject.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <application android:label="Safer" android:icon="@mipmap/ic_launcher" android:fullBackupContent="@xml/auto_backup_rules">
        <receiver android:name="com.onesignal.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="$br.com.safertechnology.saferproject" />
            </intent-filter>
        </receiver>
    </application>
    <uses-permission android:name="$com.aolserra.sirene.permission.C2D_MESSAGE" />
    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
</manifest>

iOS端音频服务实现

[assembly: Xamarin.Forms.Dependency(typeof(PlaySoundService))]
namespace SaferProject.iOS.Services
{
    public class PlaySoundService : IPlaySoundService
    {
        private static PlaySoundService _instance;
        readonly SystemSound Sound;
        bool IsPlaying;

        public static PlaySoundService GetInstance()
        {
            if (_instance == null)
            {
                _instance = new PlaySoundService();
            }
            return _instance;
        }

        public PlaySoundService()
        {
            AVAudioSession audioSession = AVAudioSession.SharedInstance();
            NSError error;
            audioSession.OverrideOutputAudioPort(AVAudioSessionPortOverride.Speaker, out error);

            Sound = new SystemSound(1151); //1304 (警报音)
        }

        public Task PlaySystemSound()
        {
            Sound.PlaySystemSound();
            Vibration.Vibrate(500);
            SetServiceStatus(true);

            return Task.CompletedTask;
        }

        public Task StopSystemSound()
        {
            Sound.Close();
            Vibration.Cancel();
            SetServiceStatus(false);

            return Task.CompletedTask;
        }

        public void SetServiceStatus(bool isPlaying)
        {
            IsPlaying = isPlaying;
        }

        public bool GetServiceStatus()
        {
            return IsPlaying;
        }
    }
}

iOS AppDelegate代码

namespace SaferProject.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());

            base.FinishedLaunching(app, options);

            OneSignal.Current.SetLogLevel(LOG_LEVEL.VERBOSE, LOG_LEVEL.NONE);

            OneSignal.Current.StartInit("417d7b75-ed42-4ca5-aed3-42612d260235")
            .Settings(new Dictionary<string, bool>() {
                { IOSSettings.kOSSettingsKeyAutoPrompt, false },
                { IOSSettings.kOSSettingsKeyInAppLaunchURL, false } })
            .InFocusDisplaying(OSInFocusDisplayOption.Notification)
            .EndInit();

            OneSignal.Current.RegisterForPushNotifications();

            return true;
        }
    }
}

iOS Info.plist配置

Info.plist配置截图


内容的提问来源于stack exchange,提问作者A. Serra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 05:06:08