英文:
PendingIntent.GetBroadcast in C# is not letting me create notifications
问题
我目前正在尝试在Visual Studio使用Xamarin创建通知,但在Android应用程序中遇到了问题。
这是通知服务类,它连接到通知接收器,然后应在一定秒数后发送通知。问题是,pendingIntent.GetBroadcast
这一行总是阻止代码执行。没有出现错误消息,所以我不确定为什么这一行是错误的。
是否有人可以提供建议或指出问题所在?还是最好放弃这个方法,尝试新的方法?
我非常愿意提供任何进一步的信息,以帮助确定问题在哪里。WriteLine
命令只是为了查看代码的执行进度,大致会说"Testing 2"。
using System;
using System.Runtime.Remoting.Contexts;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Support.V4.App;
using WCDP_FMRS.Services;
using Context = Android.Content.Context;
namespace WCDP_FMRS.Droid.Services
{
// 为Android实现INotificationService
public class AndroidNotificationService : INotificationService
{
public void ScheduleNotification(string title, string message, int seconds)
{
Console.WriteLine("Testing 1");
var alarmIntent = new Intent(Application.Context, typeof(AndroidNotificationReceiver));
var notifyTime = DateTime.Now.AddSeconds(seconds);
alarmIntent.PutExtra("title", title);
alarmIntent.PutExtra("message", message);
Console.WriteLine("Testing 2");
var pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
var alarmManager = Application.Context.GetSystemService(Context.AlarmService) as AlarmManager;
Console.WriteLine("Testing 2.5");
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
alarmManager.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, notifyTime.ToLocalTime().Ticks / 10000, pendingIntent);
Console.WriteLine("Testing 3");
}
else if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
{
alarmManager.SetExact(AlarmType.RtcWakeup, notifyTime.ToLocalTime().Ticks / 10000, pendingIntent);
Console.WriteLine("Testing 4");
}
else
{
alarmManager.Set(AlarmType.RtcWakeup, notifyTime.ToLocalTime().Ticks / 10000, pendingIntent);
Console.WriteLine("Testing 5");
}
Console.WriteLine("Testing 6");
}
public void RequestAuthorization()
{
NotificationChannelHelper.CreateNotificationChannel(Application.Context);
}
}
}
英文:
I'm currently trying to create notifications in Visual Studio using Xamarin, and I'm having trouble with the Android app.
This is the notification service class that connects to the notification reciever, then should send a notification after a certain number of seconds. Problem is, the line with pendingIntent.GetBroadcast always stops the code in its tracks. No error message appears, so I'm not sure why this particular line is incorrect.
Could anyone give advice or point out what's wrong? Or would it be better to scrap this and trya new approach.
I'm more than happy to provide any further information to help determine what is wrong. The WriteLine commands are just to see how far along the code gets, and it goes about as far as saying "Testing 2"
using System;
using System.Runtime.Remoting.Contexts;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Support.V4.App;
using WCDP_FMRS.Services;
using Context = Android.Content.Context;
namespace WCDP_FMRS.Droid.Services
{
// Implement the INotificationService for Android
public class AndroidNotificationService : INotificationService
{
public void ScheduleNotification(string title, string message, int seconds)
{
Console.WriteLine("Testing 1");
var alarmIntent = new Intent(Application.Context, typeof(AndroidNotificationReceiver));
var notifyTime = DateTime.Now.AddSeconds(seconds);
alarmIntent.PutExtra("title", title);
alarmIntent.PutExtra("message", message);
Console.WriteLine("Testing 2");
**var pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);**
var alarmManager = Application.Context.GetSystemService(Context.AlarmService) as AlarmManager;
Console.WriteLine("Testing 2.5");
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
alarmManager.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, notifyTime.ToLocalTime().Ticks / 10000, pendingIntent);
Console.WriteLine("Testing 3");
}
else if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
{
alarmManager.SetExact(AlarmType.RtcWakeup, notifyTime.ToLocalTime().Ticks / 10000, pendingIntent);
Console.WriteLine("Testing 4");
}
else
{
alarmManager.Set(AlarmType.RtcWakeup, notifyTime.ToLocalTime().Ticks / 10000, pendingIntent);
Console.WriteLine("Testing 5");
}
Console.WriteLine("Testing 6");
}
public void RequestAuthorization()
{
NotificationChannelHelper.CreateNotificationChannel(Application.Context);
}
}
}
答案1
得分: 0
从PendingIntent.FLAG_MUTABLE的文档中我们可以知道:
> 在Build.VERSION_CODES.R
之前,默认情况下假定PendingIntents
是可变的,除非设置了FLAG_IMMUTABLE
。从Build.VERSION_CODES.S
开始,将需要在创建时明确指定PendingIntents
的可变性,要么使用{@link #FLAG_IMMUTABLE},要么使用FLAG_MUTABLE
。强烈建议在创建PendingIntent
时使用FLAG_IMMUTABLE
。只有在某些功能依赖于修改底层意图的情况下,才应该使用FLAG_MUTABLE
,例如需要与内联回复或气泡一起使用的任何PendingIntent
。
因此,您可以尝试将代码:
var pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
替换为:
var pendingIntentFlags = (Build.VERSION.SdkInt >= BuildVersionCodes.S)
? PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Mutable
: PendingIntentFlags.UpdateCurrent;
var pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, resultIntent, pendingIntentFlags);
英文:
From documentation of PendingIntent.FLAG_MUTABLE,we know that :
> Up until Build.VERSION_CODES.R
, PendingIntents
are assumed to be
> mutable by default, unless FLAG_IMMUTABLE
is set. Starting with
> Build.VERSION_CODES.S
, it will be required to explicitly specify the
> mutability of PendingIntents on creation with either (@link
> #FLAG_IMMUTABLE} or FLAG_MUTABLE
. It is strongly recommended to use
> FLAG_IMMUTABLE
when creating a PendingIntent
. FLAG_MUTABLE
should
> only be used when some functionality relies on modifying the
> underlying intent, e.g. any PendingIntent
that needs to be used with
> inline reply or bubbles.
So, you can try to replace code :
var pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
with:
var pendingIntentFlags = (Build.VERSION.SdkInt >= BuildVersionCodes.S)
? PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Mutable
: PendingIntentFlags.UpdateCurrent;
var pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, resultIntent, pendingIntentFlags);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论