目标:将自定义wav设置为应用的默认推送通知声音。
我有一个Wave文件,该文件位于Android的“ FilesDir”中。我使用Xamarin.Essentials FileSystem助手在FileSystem.AppDataDirectory中创建了该文件,该文件实际上是一个录音。
在Debug中检查时,wav文件的确切位置是:
/data/user/o/com.company.appname/files/fileName.Wav
我需要将此文件设置为我的应用程序的默认推送通知声音。 目前,我已经设置了一个通知通道,但是所使用的通知声音(和预期的效果)驻留在res / raw中。
我该如何实现?
似乎我无法使其成为当前位置的默认推送通知声音。我必须将其复制到Ringtone文件夹或res / raw文件夹,但是在应用程序运行时如何动态地将其复制(将文件复制到相应位置作为通知声音)?甚至可以在APK中进行文件传输吗?
这是我在创建推送通知频道时尝试过的方法,但是没有用:
//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中,则可能会起作用,但是声音会在运行时自定义录制...
答案 0 :(得分:1)
查看适用于Android的FileSystem.AppDataDirectory
的Xamarin Essentials源代码,
您要将录制的声音文件保存到内部存储(文件目录)。 Files目录是专用目录,只能由您的应用程序访问。用户或操作系统都无法访问该文件。您必须将文件保存在Public External Storage或Private External Storage中。这取决于您是否希望MediaStore内容提供商访问录制的声音文件。
答案 1 :(得分:0)
我想出了怎么做,可能会帮助尝试这样做的人。解决方法如下:
如@SharpMoibileCode所述,在使用Xamarin Essentials文件系统助手时,尤其是在使用路径 FileSystem.AppDataDirectory 保存记录时,它将保存在内部存储中。它的路径是这样的:
/data/user/0/com.company.appname/files/customsoundfilename.wav
为了在运行时自定义频道的“推送通知”声音,声音文件必须保存到公共外部存储,即 Android.OS.Environment.ExternalStorageDirectory < / strong>,其路径如下:
/ storage / emulated / 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);
}
}