Search code examples
androidxamarinxamarin.android

Custom notification sound does not play in android


I created a dependencyservice, but in android the custom notification sound does not play.

What tried:

  • I created many version, but the result is the same, no custom sound.
  • I can set default sound, and its play well, but i need only custom sound.
  • My first idea is the uri, that maybe wrong, but i created 4-5 version of the uri, but the result is the same.

My audio file location is resources/raw folder

Someone faced this problem before?

Here is my code:

public class AndroidNotificationManager : INotificationManager
    {
        const string channelId = "default";
        const string channelName = "Default";
        const string channelDescription = "The default channel for notifications.";
        const int pendingIntentId = 0;

        public const string TitleKey = "title";
        public const string MessageKey = "message";

        bool channelInitialized = false;
        NotificationManager manager;
        private string soundFileName;

        public event EventHandler NotificationReceived;

        public void Initialize()
        {
            CreateNotificationChannel();
        }

        public int ScheduleNotification(string title, string message, int messageId, string soundFileName = "")
        {
            if (!channelInitialized)
            {
                CreateNotificationChannel();
            }

            this.soundFileName = soundFileName;
            Intent intent = new Intent(AndroidApp.Context, typeof(MainActivity));
            intent.PutExtra(TitleKey, title);
            intent.PutExtra(MessageKey, message);

            PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId, intent, PendingIntentFlags.OneShot);

            NotificationCompat.Builder builder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
                .SetContentIntent(pendingIntent)
                .SetContentTitle(title)
                .SetContentText(message)
                .SetLargeIcon(BitmapFactory.DecodeResource(AndroidApp.Context.Resources, Resource.Drawable.ic_launcher))
                .SetSmallIcon(Resource.Drawable.ic_launcher)
                .SetVibrate(null);

            if (!string.IsNullOrEmpty(soundFileName))
            {
                builder.SetDefaults((int)NotificationDefaults.Lights);
                var uri = Uri.Parse($"{ContentResolver.SchemeAndroidResource}://{AndroidApp.Context.PackageName}/raw/alarm.wav");
                builder.SetSound(uri);
            }
            else
            {
                builder.SetDefaults((int) NotificationDefaults.Lights);
                builder.SetSound(null);
            }

            Notification notification = builder.Build();
            manager.Notify(messageId, notification);

            return messageId;
        }

        public void ReceiveNotification(string title, string message)
        {
            var args = new NotificationEventArgs()
            {
                Title = title,
                Message = message,
            };
            NotificationReceived?.Invoke(null, args);
        }

        void CreateNotificationChannel()
        {
            manager = (NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                var channelNameJava = new Java.Lang.String(channelName);
                var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Default)
                {
                    Description = channelDescription
                };
                channel.SetVibrationPattern(new long[] { 0 });
                channel.EnableVibration(true);
                channel.EnableLights(true);

                // Creating an Audio Attribute
                var alarmAttributes = new AudioAttributes.Builder()
                    .SetContentType(AudioContentType.Sonification)
                    .SetUsage(AudioUsageKind.Notification).Build();

                if (!string.IsNullOrEmpty(soundFileName))
                {
                    var uri = Uri.Parse($"{ContentResolver.SchemeAndroidResource}://{AndroidApp.Context.PackageName}/raw/alarm.wav");
                    channel.SetSound(uri, alarmAttributes);
                }
                else
                {
                    channel.SetSound(null, null);
                }

                manager.CreateNotificationChannel(channel);
            }

            channelInitialized = true;
        }
    }

Solution

  • The URI you are creating is wrong, that is why it is not picked up. It needs to look something like: android.resource://<packagename>/<resourceId>

    So in your case something like this should work:

    var uri = Uri.Parse($"android.resource://{AndroidApp.Context.PackageName}/{Resources.Raw.alarm}");
    

    Given that the file alarm is in Resources/raw/