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配置

内容的提问来源于stack exchange,提问作者A. Serra
相关产品推荐
相关产品推荐

