C# 中的 PendingIntent.GetBroadcast 不允许我创建通知。

huangapple go评论85阅读模式
英文:

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);

huangapple
  • 本文由 发表于 2023年6月16日 07:45:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76486131.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定