我正在尝试在显示本地通知时在Android平台上播放自定义声音,下面的代码基于Xamarin Local Notification Documentation,但是某些我被唠叨的字段已经过时/弃用。
特别是 SetSound
然而,我尝试使用SetSound,希望它仍然可以工作,即使已弃用。但我不知道如何引用Android / Xamarin' Asset'中的mp3文件。我在Android / Xamarin' Resources / raw'中的文件夹或副本夹。
/资产内容具有构建操作AndroidAsset
/ Resources / raw contents有构建动作AndroidResource
这条线是令我头痛的原因......
.SetSound(Android.Net.Uri.Parse(" android.resource://MyAssemblyName.Droid/Assets/filename"));
也尝试了
.SetSound(Android.Net.Uri.Parse(" android.resource://MyAssemblyName.Resources/raw/filename"));
Q1)使用Assets或Resources文件夹正确播放自定义通知声音需要做什么?
Q2)因为SetSound已被弃用,我打算做什么呢?
我已经作弊,部分成功,我有一个播放声音的Xamarin插件,它引用了便携式类库(PCL)中的相同文件,并且该机制可以工作(当未注释时),但仅当应用程序在前景。
如果我刷到“杀死”,似乎我的预定本地通知不会触发。应用程序,即使应用程序不会因为我有一个持久的通知阻止应用程序关闭(直到将来的某个时间发布持续通知,可能会在几分钟后)。
问题3)一旦用户滑动应用程序,为什么不会触发计划的本地通知,即使持久系统通知让应用程序保持运行?以下是如何设置持久性通知的方法。如果不是这个问题,我可能会通过上面详述的黑客来播放来自PCL的声音。
var activity = new Intent(Android.App.Application.Context, typeof(MainActivity));
var pIntent = PendingIntent.GetActivity(this, 0, activity, 0);
var notification = new Notification.Builder(this)
.SetContentTitle("Persistent Notification Test")
.SetContentText("This is always running to ensure that you are safe.")
.SetSmallIcon(Resource.Drawable.icon)
.SetOngoing(true)
.SetDefaults(0) // no sounds
.SetContentIntent(pIntent)
.Build();
// Enlist this instance of the service as a foreground service
StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
对于那些感兴趣的人,注释掉的行
// PlatformDifferences.PlaySound(soundFilename, Logger);
调用此方法使用SimpleAudioPlayer插件
public virtual void PlaySound(string soundFilenameExcludingPath, Logger logger) {
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(App)).Assembly;
Stream audioStream = assembly.GetManifestResourceStream("<my-pcl-assembly-name>.Sounds." + soundFilenameExcludingPath);
if (audioStream != null)
{
logger.Log(this, "playing sound:" + soundFilenameExcludingPath);
var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.Load(audioStream);
player.Play();
}
else
{
logger.Log(this, "failed - playing sound:" + soundFilenameExcludingPath);
}
}
这是一个显示我的项目结构的屏幕截图
以下是我想要显示通知时调用的方法,无论是因为我想要预定的本地通知,还是因为我已收到推送通知并希望向我们显示详细信息用户。
private async Task DisplayLocalNotification(String title, String message, String soundFilename)
{
Logger.Log(this, "DisplayLocalNotification title:" + title + " message:" + message);
// Ensure the main activity is lauched when the app is started.
Intent secondIntent = new Intent(Android.App.Application.Context, typeof(MainActivity));
Notification.BigTextStyle textStyle = new Notification.BigTextStyle();
textStyle.BigText(message);
int length = message.Length;
if (length > 80)
{
length = 80;
}
textStyle.SetSummaryText(message.Substring(0, length));
const int pendingIntentId = 0;
PendingIntent pendingEventForMainActivity =
PendingIntent.GetActivity(Android.App.Application.Context, pendingIntentId, secondIntent, PendingIntentFlags.OneShot);
Notification.Builder builder = new Notification.Builder(Android.App.Application.Context)
.SetContentTitle(title)
.SetContentText(message)
.SetAutoCancel(true)
.SetContentIntent(pendingEventForMainActivity)
//.SetWhen () // - Now
.SetSmallIcon(Resource.Drawable.icon)
.SetVisibility(NotificationVisibility.Public)
.SetCategory(Notification.CategoryEvent)
.SetStyle(textStyle)
//.SetSound(Asset);?? What import?
//.SetSound(RingtoneManager.) ?? Looks like it's a fixed list of alert sounds
.SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate) // << DEPRECATD
.SetSound(Android.Net.Uri.Parse("android.resource://My-Assembly.Droid/Assets/" + soundFilename)); // << DEPECATD
// Hack - Works (if in foreground, but no if swipe-to-kill)...
// PlatformDifferences.PlaySound(soundFilename, Logger);
// Example: .SetSound(Uri.Parse("android.resource://" + this.PackageName + "/Raw/" + Resource.Raw.woop));
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
builder.SetSmallIcon(Resource.Drawable.icon);// Resource.Drawable.icon_transparent);
}
else
{
builder.SetSmallIcon(Resource.Drawable.icon);
}
// Create a task stack builder to manage the back stack:
TaskStackBuilder stackBuilder = TaskStackBuilder.Create(Android.App.Application.Context);
// Add all parents of SecondActivity to the stack:
stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(MainActivity)));
// Push the intent that starts SecondActivity onto the stack:
stackBuilder.AddNextIntent(secondIntent);
// Build the notification:
Notification androidNotification = builder.Build();
NotificationManager notificationManager =
Android.App.Application.Context.GetSystemService(Android.Content.Context.NotificationService) as NotificationManager;
// Publish the notification:
int notificationId = await StorageService.increment(Constants.STORAGE_KEY_NOTIFICATION_COUNTER);
notificationManager.Notify(notificationId, androidNotification);
Console.Out.WriteLine("DisplayLocalNotification title:" + title + " message:" + message + " published as id:" + notificationId + "?");
}
答案 0 :(得分:0)
请参阅@SushiHangover的评论
您的屏幕截图显示的是API-27设备以及targetSdkVersion 设置好了,你需要使用NotificationChannels(你会的 需要if / else测试API级别,如我的链接示例所示)。我有 看到很多不同类型的通知失败就不同了 (API-26 +)设备,甚至模拟器中的通知都表现出来 不使用NotificationChannels时会有所不同。