Xamarin.Android Как сделать wav-файл звуком push-уведомлений по умолчанию для приложения? - PullRequest
0 голосов
/ 09 января 2019

Цель: установить пользовательский wav в качестве звука push-уведомлений по умолчанию для приложения.

У меня есть волновой файл, который находится в "FilesDir" на Android. Я использовал Xamarin.Essentials FileSystem helper для создания файла в FileSystem.AppDataDirectory, фактически это запись голоса.

Точное местоположение wav-файла при проверке в Debug:

/ данные / пользователь / о / com.company.AppName / файлы / fileName.Wav

Мне нужно сделать этот файл звуком push-уведомлений по умолчанию для моего приложения. В настоящее время у меня настроен канал уведомлений, но используемый звук уведомления (и который работает как задумано) находится в res / raw.

Как мне этого добиться?

Кажется, я не могу сделать его звуком push-уведомлений по умолчанию из его текущего местоположения. Мне пришлось бы скопировать его в папку «Мелодия звонка» или в папку «res / raw», но как я могу сделать это (скопировать файл в соответствующее место, откуда его можно использовать в качестве звукового уведомления) динамически, когда приложение работает, пожалуйста? Можно ли вообще сделать передачу файлов внутри APK?

Вот что я пробовал при создании канала push-уведомлений, но он не работал:

//Create two notif channels, the urgent channel 
// should use a custom wav as notification sound
private void createNotificationChannels()
    {
        try
        {
            // the urgent channel
            var urgentChannelName = GetString(Resource.String.noti_chan_urgent);
            var urgentChannelDescription = GetString(Resource.String.noti_chan_urgent_description);

            // the informational channel
            var infoChannelName = GetString(Resource.String.noti_chan_info);
            var infoChannelDescrption = GetString(Resource.String.noti_chan_info_description);

            // set the vibration patterns for the channels
            long[] urgentVibrationPattern = { 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100, 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100 };
            long[] infoVibrationPattern = { 100, 200, 300, 400, 500, 400, 300, 200, 400 };

            // Creating common Audio Attributes for both channels
            var alarmAttributes = new AudioAttributes.Builder()
                .SetContentType(AudioContentType.Sonification)
                .SetUsage(AudioUsageKind.Notification).Build();

            // get path of custom sound recording to use as push notification
            var recordingFileDestinationPath = System.IO.Path.Combine(FileSystem.AppDataDirectory, AppConstants.CUSTOM_ALERT_FILENAME);

            //**This is where I am trying to create the URI for the custom wav file for notification, which resides in FilesDir**
            Android.Net.Uri urgentAlarmUri = Android.Net.Uri.Parse(recordingFileDestinationPath);

            Android.Net.Uri infoAlarmUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);


            var chan1 = new NotificationChannel(PRIMARY_CHANNEL_ID, urgentChannelName, NotificationImportance.High)
            {
                Description = urgentChannelDescription
            };

            var chan2 = new NotificationChannel(SECONDARY_CHANNEL_ID, infoChannelName, NotificationImportance.Default)
            {
                Description = infoChannelDescrption
            };


            // set the urgent channel properties
            chan1.EnableLights(true);
            chan1.LightColor = Color.Red;
            chan1.SetSound(urgentAlarmUri, alarmAttributes);
            chan1.EnableVibration(true);
            chan1.SetVibrationPattern(urgentVibrationPattern);               
            chan1.SetBypassDnd(true);
            chan1.LockscreenVisibility = NotificationVisibility.Public;

            // set the info channel properties
            chan2.EnableLights(true);
            chan2.LightColor = Color.Red;
            chan2.SetSound(infoAlarmUri, alarmAttributes);
            chan2.EnableVibration(true);
            chan2.SetVibrationPattern(infoVibrationPattern);
            chan2.SetBypassDnd(false);
            chan2.LockscreenVisibility = NotificationVisibility.Public;


            var manager = (NotificationManager)GetSystemService(NotificationService);

            // create chan1  which is the urgent notifications channel
            manager.CreateNotificationChannel(chan1);
            manager.CreateNotificationChannel(chan2);


        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

Нет звука для срочного канала с вышеуказанным кодом. Если я загружаю звук из res / raw, он работает нормально. Если бы я поместил запись заранее в res / raw, это, вероятно, сработало бы, но звук записывался в обычном режиме во время выполнения ...

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Я понял, как это сделать, и мог бы помочь кому-то, пытающемуся сделать то же самое. Вот решение:

Как указано @SharpMoibileCode, при использовании помощников файловой системы Xamarin Essentials и, в частности, при сохранении записи с использованием пути FileSystem.AppDataDirectory она сохраняется во Internal Storage . Вот такой путь:

/ данные / пользователь / 0 / com.company.AppName / файлы / customsoundfilename.wav

Чтобы настроить звук push-уведомлений для канала во время выполнения, звуковой файл необходимо сохранить в Public External Storage , а именно Android.OS.Environment.ExternalStorageDirectory * 1016. * у которого есть такой путь:

/ хранение / эмулировать / 0 /.../

Теперь для записи / чтения в / из внешнего хранилища необходимы разрешения на запись во внешнее хранилище. Поэтому их необходимо добавить в манифест:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Но этого недостаточно. Разрешение необходимо запросить непосредственно перед тем, как получить доступ к внешнему хранилищу следующим образом (используя плагин NuGet «Текущий проект для Android», чтобы получить текущее действие):

var currentActivity = CrossCurrentActivity.Current.Activity;
            int requestCode=1;

            ActivityCompat.RequestPermissions(currentActivity, new string[] {
                Manifest.Permission.ReadExternalStorage,
                Manifest.Permission.WriteExternalStorage
            }, requestCode);

если разрешение предоставлено, продолжить и скопировать файл на внешнее хранилище:

var recordingFileExternalPath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, AppConstants.CUSTOM_ALERT_FILENAME);

            if (ContextCompat.CheckSelfPermission(Android.App.Application.Context, Manifest.Permission.WriteExternalStorage) == (int)Permission.Granted)
            {
                try
                {
                    if (File.Exists(recordingFileExternalPath))
                    {
                        File.Delete(recordingFileExternalPath);
                    }

                    File.Copy(filePath, recordingFileExternalPath);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            else
            {
                UserDialogs.Instance.Alert("Permission to write to External Storage not approved, cannot save settings.", "Permission Denied", "Ok");
            }

А теперь, наконец, установите скопированный выше звук как уведомление для канала:

try
            {
                // the urgent channel
                var urgentChannelName = GetString(Resource.String.noti_chan_urgent);
                var urgentChannelDescription = GetString(Resource.String.noti_chan_urgent_description);


                // set the vibration patterns for the channels
                long[] urgentVibrationPattern = { 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100, 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100 };

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

                // Create the uri for the alarm file

                var recordingFileDestinationPath = System.IO.Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, AppConstants.CUSTOM_ALERT_FILENAME);

                Android.Net.Uri urgentAlarmUri = Android.Net.Uri.Parse(recordingFileDestinationPath);



                var chan1 = new NotificationChannel(PRIMARY_CHANNEL_ID, urgentChannelName, NotificationImportance.High)
                {
                    Description = urgentChannelDescription
                };


                // set the urgent channel properties
                chan1.EnableLights(true);
                chan1.LightColor = Color.Red;
                chan1.SetSound(urgentAlarmUri, alarmAttributes);
                chan1.EnableVibration(true);
                chan1.SetVibrationPattern(urgentVibrationPattern);               
                chan1.SetBypassDnd(true);
                chan1.LockscreenVisibility = NotificationVisibility.Public;



                var manager = (NotificationManager)GetSystemService(NotificationService);

                // create chan1  which is the urgent notifications channel
                manager.CreateNotificationChannel(chan1);

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
0 голосов
/ 09 января 2019

Глядя на исходный код Xamarin Essentials для FileSystem.AppDataDirectory для Android,

https://github.com/xamarin/Essentials/blob/master/Xamarin.Essentials/FileSystem/FileSystem.android.cs#L14

Вы сохраняете записанный звуковой файл во внутреннее хранилище (каталог файлов). Каталог Files - это личный каталог, доступный только вашему приложению. Ни пользователь, ни ОС не могут получить доступ к этому файлу. Вам нужно будет сохранить файл в Public External Storage или Private External Storage . Это зависит от того, хотите ли вы, чтобы ваш записанный звуковой файл был доступен поставщиком контента MediaStore.

...