在 Xamarin 中推送通知 android 问题

Pushing notification in Xamarin android problem

我正在 Xamarin 上制作一个提醒应用程序,我正在尝试推送通知。

目前,我的应用不会发送通知,而是会打开一个空白 activity,如下所示:

这是我的一些代码:

namespace ReminderApp.Models
{
    public class Reminder
    {
        public int Id { get; set; }
        public string Date { get; set; }
        public string Time { get; set; }
        public string Note { get; set; }
        public Reminder()
        {
        }
    }
}

通知Activity

using Android.App;
using Android.Content;
using Newtonsoft.Json;
using ReminderApp.Models;
using ReminderApp.HelperRepository;
using Android.OS;

namespace ReminderApp.Notifications
{
    [Activity(Label = "ReminderApp")]
    public class ReminderNotifications : Activity
    {
        Reminder reminder;
        public ReminderNotifications()
        {
        }

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);


            var channel = new NotificationChannel("dan1414", "FCMDD Notifications", NotificationImportance.Default)
            {
                Description = "Cloud Messages appear in this channel"
            };

            reminder = ReminderHelper.SelectReminder(this);
            if (reminder != null)
            {
                Intent newIntent = new Intent(this, typeof(ReminderContent));
                newIntent.PutExtra("reminder", JsonConvert.SerializeObject(reminder));

                Android.Support.V4.App.TaskStackBuilder stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(this);
                stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(ReminderContent)));
                stackBuilder.AddNextIntent(newIntent);

                PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);

                Notification.Builder builder = new Notification.Builder(this, channel.Id)
                .SetAutoCancel(true)
                .SetContentIntent(resultPendingIntent)
                .SetContentTitle("Reminder!!")
                .SetSmallIcon(Resource.Drawable.Screenshot_2020_11_11_at_4_57_02_PM)
                .SetContentText("Click for details..");
                //.SetContentInfo("Start");
                NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
                notificationManager.CreateNotificationChannel(channel);
                notificationManager.Notify(0, builder.Build());
            }
        }
    }
}

主要代码:

using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using Newtonsoft.Json;
using ReminderApp.Models;
using ReminderApp.HelperRepository;
using ReminderApp.Notifications;

namespace ReminderApp
{
    [Activity(Label = "ReminderApp", MainLauncher = true)]
    public class MainActivity : Activity
    {
        public Reminder reminder;
        EditText _dateDisplay;
        EditText _timeDisplay;
        EditText _txtNote;
        Button _saveButton;
        Button _btnList;

        #region DateOperation  
        [Obsolete]
        void DateSelect_OnClick(object sender, EventArgs eventArgs)
        {
            DatePickerFragment frag = DatePickerFragment.NewInstance(delegate (DateTime time)
            {
                _dateDisplay.Text = time.ToString().Split(' ')[0];
                reminder.Date = _dateDisplay.Text + " ";
            });
            frag.Show(FragmentManager, DatePickerFragment.TAG);
        }
        #endregion

        #region TimeOperation  
        [Obsolete]
        void TimeSelectOnClick(object sender, EventArgs eventArgs)
        {
            TimePickerFragment frag = TimePickerFragment.NewInstance(
                delegate (DateTime time)
                {
                    _timeDisplay.Text = time.ToShortTimeString();
                    reminder.Time = _timeDisplay.Text + " ";
                });

            frag.Show(FragmentManager, TimePickerFragment.TAG);
        }
        #endregion

        #region SaveDetails  
        void SaveRecords(object sender, EventArgs eventArgs)
        {
            reminder.Note = _txtNote.Text;
            if (Vaidate())
            {
                DateTime currentDT = DateTime.Now;
                DateTime selectedDT = Convert.ToDateTime(reminder.Date + " " + reminder.Time);

                if (selectedDT > currentDT)
                {
                    ReminderHelper.InsertReminderData(this, reminder);
                    ScheduleReminder(reminder);
                    var reminderAdded = new Intent(this, typeof(ReminderAdded));
                    reminderAdded.PutExtra("reminder", JsonConvert.SerializeObject(reminder));
                    StartActivity(reminderAdded);
                }
                else
                {
                    Toast.MakeText(this, "This is invalid selelction of Date, Time!", ToastLength.Short).Show();
                }
            }

        }

        bool Vaidate()
        {
            if (reminder.Date == string.Empty || reminder.Time == string.Empty || reminder.Note == string.Empty)
            {
                Toast.MakeText(this, "Enter the details of all fields!", ToastLength.Short).Show();
                return false;
            }
            return true;
        }
        #endregion

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.activity_main);
            reminder = new Reminder();
            _dateDisplay = FindViewById<EditText>(Resource.Id.date_display);
            _timeDisplay = FindViewById<EditText>(Resource.Id.time_display);
            _txtNote = FindViewById<EditText>(Resource.Id.txtNote);

            _saveButton = FindViewById<Button>(Resource.Id.save);
            _btnList = FindViewById<Button>(Resource.Id.btnList);

            _dateDisplay.Click += DateSelect_OnClick;
            _timeDisplay.Click += TimeSelectOnClick;
            _saveButton.Click += SaveRecords;

            _btnList.Click += (sender, e) => {
                StartActivity(new Intent(this, typeof(ListReminder)));
            };
        }

        public void ScheduleReminder(Reminder reminder)
        {
            AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
            Intent myIntent;
            PendingIntent pendingIntent;
            myIntent = new Intent(this, typeof(ReminderNotifications));
 
            var t = reminder.Time.Split(':');
            var ampm = t[1].Split(' ')[1];
            var hrr = Convert.ToDouble(t[0]);
            var min = Convert.ToDouble(t[1].Split(' ')[0]);

            string dateString = Convert.ToString(reminder.Date + " " + hrr + ":" + min + ":00 " + ampm);

            DateTimeOffset dateOffsetValue = DateTimeOffset.Parse(dateString);
            var millisec = dateOffsetValue.ToUnixTimeMilliseconds();

            pendingIntent = PendingIntent.GetActivity(this, 0, myIntent, 0);
            manager.Set(AlarmType.RtcWakeup, millisec, pendingIntent);
        }
    }
}

Activity点击通知时打开:

using Android.App;  
using Android.Content;  
using Android.OS;  
using Android.Widget;  
using Newtonsoft.Json;  
using ReminderApp.Models;  
using ReminderApp.HelperRepository;  
  
namespace ReminderApp
{
    [Activity(Label = "ReminderContent")]
    public class ReminderContent : Activity
    {
        Reminder reminder;
        TextView _txtNote;
        Button _btnBack;
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.ReminderContent);

            // Create your application here  
            reminder = JsonConvert.DeserializeObject<Reminder>(Intent.GetStringExtra("reminder"));
            ReminderHelper.DeleteReminder(this, reminder);
            _txtNote = FindViewById<TextView>(Resource.Id.txt_note);
            _txtNote.Text = reminder.Note;
            _btnBack = FindViewById<Button>(Resource.Id.btn_back);
            _btnBack.Click += (sender, e) => {
                StartActivity(new Intent(this, typeof(ListReminder)));
            };
        }
    }
}

我做错了什么?

如果需要,这是我的完整代码:https://github.com/CrazyDanyal1414/ReminderApp

感谢任何帮助!

如果出现空白屏幕,则应创建布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
        android:text="ringing"
        android:textSize="100dp"/>
</LinearLayout>

打开您的 ReminderNotifications,在 OnCreate 方法中通过 SetContentView(Resource.Layout.Alertlayout); 添加此布局。

using Android.App;
using Android.Content;
using Newtonsoft.Json;
using reminderapp.Models;
using reminderapp.HelperRepository;
using Android.OS;

namespace reminderapp.Notifications
{
    //[BroadcastReceiver(Enabled = true)]
    [Activity(Label = "ReminderApp")]
    public class ReminderNotifications : Activity
    {
        Reminder reminder;
        public ReminderNotifications()
        {
        }
        string CHANNEL_ID = "dan1414";
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Alertlayout);

            var channel = new NotificationChannel(CHANNEL_ID, "FCMDD Notifications", NotificationImportance.Default)
            {
                Description = "Cloud Messages appear in this channel"
            };
        string date=    this.Intent.GetStringExtra("date");
         string time=   this.Intent.GetStringExtra("time");
            reminder = ReminderHelper.SelectReminderByDateAndTime(Application.Context, date, time);
            if (reminder != null)
            {
                Intent newIntent = new Intent(this, typeof(ReminderContent));
                newIntent.PutExtra("reminder", JsonConvert.SerializeObject(reminder));

                Android.Support.V4.App.TaskStackBuilder stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(this);
                stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(ReminderContent)));
                stackBuilder.AddNextIntent(newIntent);

                PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);

                Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
                .SetAutoCancel(true)
                .SetContentIntent(resultPendingIntent)
                .SetContentTitle("Reminder!!")
                .SetSmallIcon(Resource.Drawable.Screenshot_2020_11_11_at_4_57_02_PM)
                .SetContentText("Click for details..");
                //.SetContentInfo("Start");
                NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
                notificationManager.CreateNotificationChannel(channel);
                notificationManager.Notify(0, builder.Build());
            }
        }

    
    }
}

我调试了你的代码,我发现reminder = ReminderHelper.SelectReminder(Application.Context);无法从sqlite DB中获取数据。

所以,我们可以改变过滤方式,首先,请打开MainActivity.cs,找到ScheduleReminder方法。我将datetime发送到ReminderNotifications.cs,我们可以在ReminderNotifications.csdatedatetime中得到datetime time 将帮助我们在数据库中执行查询

 public void ScheduleReminder(Reminder reminder)
        {
            AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
            Intent myIntent;
            PendingIntent pendingIntent;
            myIntent = new Intent(this, typeof(ReminderNotifications));
            myIntent.PutExtra("date", reminder.Date);
            myIntent.PutExtra("time", reminder.Time);
            var t = reminder.Time.Split(':');
            var ampm = t[1].Split(' ')[1];
            var hrr = Convert.ToDouble(t[0]);
            var min = Convert.ToDouble(t[1].Split(' ')[0]);

            string dateString = Convert.ToString(reminder.Date + " " + hrr + ":" + min + ":00 " + ampm);

            DateTimeOffset dateOffsetValue = DateTimeOffset.Parse(dateString);
            var millisec = dateOffsetValue.ToUnixTimeMilliseconds();

            pendingIntent = PendingIntent.GetActivity(this, 0, myIntent, 0);
            manager.Set(AlarmType.RtcWakeup, millisec, pendingIntent);
        }

所以,我在 ReminderHelper.cs.

中写了一个新方法
 public static Reminder SelectReminderByDateAndTime(Context context, string date, string time )
        {
            Reminder reminder;
            SQLiteDatabase db = new DataStore(context).WritableDatabase;
            string[] columns = new string[] { ColumnID, ColumnDate, ColumnTime, ColumnNote };
            using (ICursor cursor = db.Query(TableName, columns, ColumnDate + "=? AND " + ColumnTime + "=?", new string[] { date, time }, null, null, null))
            {
                if (cursor.MoveToNext())
                {
                    reminder = new Reminder
                    {
                        Id = cursor.GetInt(cursor.GetColumnIndexOrThrow(ColumnID)),
                        Date = cursor.GetString(cursor.GetColumnIndexOrThrow(ColumnDate)),
                        Time = cursor.GetString(cursor.GetColumnIndexOrThrow(ColumnTime)),
                        Note = cursor.GetString(cursor.GetColumnIndexOrThrow(ColumnNote))
                    };
                }
                else
                {
                    reminder = null;
                }
            }
            return reminder;

        }

这是运行 GIF。