yerel bildirimler Xamarin.Forms
Yerel bildirimler, mobil cihazda yüklü uygulamalar tarafından gönderilen uyarılardır. Yerel bildirimler genellikle aşağıdakiler gibi özellikler için kullanılır:
- Takvim olayları
- Anımsatıcılar
- Konum tabanlı tetikleyiciler
Her platform yerel bildirimlerin oluşturulmasını, görüntülenmesini ve tüketimini farklı şekilde işler. Bu makalede ile Xamarin.Formsyerel bildirimler göndermek, zamanlamak ve almak için platformlar arası soyutlamanın nasıl oluşturulacağı açıklanır.
Platformlar arası arabirim oluşturma
Uygulamanın Xamarin.Forms temel platform uygulamalarıyla ilgilenmeden bildirimler oluşturması ve kullanması gerekir. Aşağıdaki INotificationManager
arabirim paylaşılan kod kitaplığında uygulanır ve uygulamanın bildirimlerle etkileşime geçmek için kullanabileceği platformlar arası bir API tanımlar:
public interface INotificationManager
{
event EventHandler NotificationReceived;
void Initialize();
void SendNotification(string title, string message, DateTime? notifyTime = null);
void ReceiveNotification(string title, string message);
}
Bu arabirim her platform projesinde uygulanacaktır. Olay, NotificationReceived
uygulamanın gelen bildirimleri işlemesine olanak tanır. yöntemi, Initialize
bildirim sistemini hazırlamak için gereken tüm yerel platform mantığını gerçekleştirmelidir. SendNotification
yöntemi isteğe bağlı DateTime
olarak bir bildirim göndermelidir. Bir ReceiveNotification
ileti alındığında yöntemi temel platform tarafından çağrılmalıdır.
arabirimini kullanma Xamarin.Forms
Bir arabirim oluşturulduktan sonra, platform uygulamaları henüz oluşturulmamış olsa bile paylaşılan Xamarin.Forms projede kullanılabilir. Örnek uygulama, aşağıdaki içeriğe sahip MainPage.xaml adlı bir ContentPage
içerir:
<StackLayout Margin="0,35,0,0"
x:Name="stackLayout">
<Label Text="Click the button below to create a local notification."
TextColor="Red"
HorizontalOptions="Center"
VerticalOptions="Start" />
<Button Text="Create Notification"
HorizontalOptions="Center"
VerticalOptions="Start"
Clicked="OnSendClick" />
<Label Text="Click the button below to schedule a local notification for in 10 seconds time."
TextColor="Red"
HorizontalOptions="Center"
VerticalOptions="Start" />
<Button Text="Create Notification"
HorizontalOptions="Center"
VerticalOptions="Start"
Clicked="OnScheduleClick" />
</StackLayout>
Düzen, yönergeleri açıklayan öğeleri ve Button
dokunulduğunda bildirim gönderen veya zamanlayan öğeleri içerirLabel
.
Arka MainPage
planda kod sınıfı, bildirimlerin gönderilmesini ve alınmasını işler:
public partial class MainPage : ContentPage
{
INotificationManager notificationManager;
int notificationNumber = 0;
public MainPage()
{
InitializeComponent();
notificationManager = DependencyService.Get<INotificationManager>();
notificationManager.NotificationReceived += (sender, eventArgs) =>
{
var evtData = (NotificationEventArgs)eventArgs;
ShowNotification(evtData.Title, evtData.Message);
};
}
void OnSendClick(object sender, EventArgs e)
{
notificationNumber++;
string title = $"Local Notification #{notificationNumber}";
string message = $"You have now received {notificationNumber} notifications!";
notificationManager.SendNotification(title, message);
}
void OnScheduleClick(object sender, EventArgs e)
{
notificationNumber++;
string title = $"Local Notification #{notificationNumber}";
string message = $"You have now received {notificationNumber} notifications!";
notificationManager.SendNotification(title, message, DateTime.Now.AddSeconds(10));
}
void ShowNotification(string title, string message)
{
Device.BeginInvokeOnMainThread(() =>
{
var msg = new Label()
{
Text = $"Notification Received:\nTitle: {title}\nMessage: {message}"
};
stackLayout.Children.Add(msg);
});
}
}
MainPage
Sınıf oluşturucu, Xamarin.FormsDependencyService
platforma özgü bir örneğini INotificationManager
almak için öğesini kullanır. OnSendClick
ve OnScheduleClicked
yöntemleri, yeni bildirimler göndermek ve zamanlamak için örneğini INotificationManager
kullanır. ShowNotification
yöntemi, olaya bağlı NotificationReceived
olay işleyicisinden çağrılır ve olay çağrıldığında sayfaya yeni Label
bir ekler.
Olay işleyicisi NotificationReceived
, olay bağımsız değişkenlerini öğesine NotificationEventArgs
yayınlar. Bu tür paylaşılan Xamarin.Forms projede tanımlanır:
public class NotificationEventArgs : EventArgs
{
public string Title { get; set; }
public string Message { get; set; }
}
hakkında Xamarin.FormsDependencyService
daha fazla bilgi için bkz Xamarin.Forms . DependencyService.
Android arabirim uygulamasını oluşturma
Uygulamanın Android'de Xamarin.Forms bildirim gönderip alabilmesi için uygulamanın arabiriminin INotificationManager
bir uygulamasını sağlaması gerekir.
AndroidNotificationManager sınıfını oluşturma
AndroidNotificationManager
sınıfı arabirimini INotificationManager
uygular:
using System;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using AndroidX.Core.App;
using Xamarin.Forms;
using AndroidApp = Android.App.Application;
[assembly: Dependency(typeof(LocalNotifications.Droid.AndroidNotificationManager))]
namespace LocalNotifications.Droid
{
public class AndroidNotificationManager : INotificationManager
{
const string channelId = "default";
const string channelName = "Default";
const string channelDescription = "The default channel for notifications.";
public const string TitleKey = "title";
public const string MessageKey = "message";
bool channelInitialized = false;
int messageId = 0;
int pendingIntentId = 0;
NotificationManager manager;
public event EventHandler NotificationReceived;
public static AndroidNotificationManager Instance { get; private set; }
public AndroidNotificationManager() => Initialize();
public void Initialize()
{
if (Instance == null)
{
CreateNotificationChannel();
Instance = this;
}
}
public void SendNotification(string title, string message, DateTime? notifyTime = null)
{
if (!channelInitialized)
{
CreateNotificationChannel();
}
if (notifyTime != null)
{
Intent intent = new Intent(AndroidApp.Context, typeof(AlarmHandler));
intent.PutExtra(TitleKey, title);
intent.PutExtra(MessageKey, message);
PendingIntent pendingIntent = PendingIntent.GetBroadcast(AndroidApp.Context, pendingIntentId++, intent, PendingIntentFlags.CancelCurrent);
long triggerTime = GetNotifyTime(notifyTime.Value);
AlarmManager alarmManager = AndroidApp.Context.GetSystemService(Context.AlarmService) as AlarmManager;
alarmManager.Set(AlarmType.RtcWakeup, triggerTime, pendingIntent);
}
else
{
Show(title, message);
}
}
public void ReceiveNotification(string title, string message)
{
var args = new NotificationEventArgs()
{
Title = title,
Message = message,
};
NotificationReceived?.Invoke(null, args);
}
public void Show(string title, string message)
{
Intent intent = new Intent(AndroidApp.Context, typeof(MainActivity));
intent.PutExtra(TitleKey, title);
intent.PutExtra(MessageKey, message);
PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId++, intent, PendingIntentFlags.UpdateCurrent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetContentIntent(pendingIntent)
.SetContentTitle(title)
.SetContentText(message)
.SetLargeIcon(BitmapFactory.DecodeResource(AndroidApp.Context.Resources, Resource.Drawable.xamagonBlue))
.SetSmallIcon(Resource.Drawable.xamagonBlue)
.SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate);
Notification notification = builder.Build();
manager.Notify(messageId++, notification);
}
void CreateNotificationChannel()
{
manager = (NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channelNameJava = new Java.Lang.String(channelName);
var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Default)
{
Description = channelDescription
};
manager.CreateNotificationChannel(channel);
}
channelInitialized = true;
}
long GetNotifyTime(DateTime notifyTime)
{
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(notifyTime);
double epochDiff = (new DateTime(1970, 1, 1) - DateTime.MinValue).TotalSeconds;
long utcAlarmTime = utcTime.AddSeconds(-epochDiff).Ticks / 10000;
return utcAlarmTime; // milliseconds
}
}
}
Ad assembly
alanının üzerindeki özniteliği, arabirim uygulamasını ile DependencyService
kaydederINotificationManager
.
Android, uygulamaların bildirimler için birden çok kanal tanımlamasına olanak tanır. yöntemi, Initialize
örnek uygulamanın bildirim göndermek için kullandığı temel bir kanal oluşturur. yöntemi, SendNotification
bildirim oluşturmak ve göndermek için gereken platforma özgü mantığı tanımlar. yöntemi ReceiveNotification
, bir ileti alındığında Android işletim sistemi tarafından çağrılır ve olay işleyicisini çağırır.
SendNotification
yöntemi hemen veya tam DateTime
olarak bir yerel bildirim oluşturur. Bir bildirim, sınıfı kullanılarak AlarmManager
tam DateTime
olarak zamanlanabilir ve bildirim sınıfından türetilen BroadcastReceiver
bir nesne tarafından alınır:
[BroadcastReceiver(Enabled = true, Label = "Local Notifications Broadcast Receiver")]
public class AlarmHandler : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent?.Extras != null)
{
string title = intent.GetStringExtra(AndroidNotificationManager.TitleKey);
string message = intent.GetStringExtra(AndroidNotificationManager.MessageKey);
AndroidNotificationManager manager = AndroidNotificationManager.Instance ?? new AndroidNotificationManager();
manager.Show(title, message);
}
}
}
Önemli
Varsayılan olarak, sınıfı kullanılarak zamanlanan bildirimler cihazın yeniden başlatılmasından AlarmManager
sonra devam etmeyecektir. Ancak, cihaz yeniden başlatıldığında bildirimleri otomatik olarak yeniden zamanlamanız için uygulamanızı tasarlayabilirsiniz. Daha fazla bilgi için developer.android.com'de yinelenen alarmları zamanlama bölümünde cihaz yeniden başlatıldığında alarm başlatma bölümüne bakın. Android'de arka plan işleme hakkında bilgi için bkz . developer.android.com üzerinde arka plan işleme kılavuzu.
Yayın alıcıları hakkında daha fazla bilgi için bkz . Xamarin.Android'de Yayın Alıcıları.
Android'de gelen bildirimleri işleme
Sınıfın MainActivity
gelen bildirimleri algılaması ve örneğe bildirmesi AndroidNotificationManager
gerekir. Activity
sınıfındaki MainActivity
özniteliği değerini LaunchMode.SingleTop
belirtmelidirLaunchMode
:
[Activity(
//...
LaunchMode = LaunchMode.SingleTop]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
// ...
}
Mod, SingleTop
uygulama ön plandayken birden Activity
çok örneğinin başlatılmasını engeller. Bu LaunchMode
, daha karmaşık bildirim senaryolarında birden çok etkinlik başlatan uygulamalar için uygun olmayabilir. Numaralandırma değerleri hakkında LaunchMode
daha fazla bilgi için bkz . Android Activity LaunchMode.
MainActivity
sınıfında, gelen bildirimleri alacak şekilde değiştirilir:
protected override void OnCreate(Bundle savedInstanceState)
{
// ...
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
CreateNotificationFromIntent(Intent);
}
protected override void OnNewIntent(Intent intent)
{
CreateNotificationFromIntent(intent);
}
void CreateNotificationFromIntent(Intent intent)
{
if (intent?.Extras != null)
{
string title = intent.GetStringExtra(AndroidNotificationManager.TitleKey);
string message = intent.GetStringExtra(AndroidNotificationManager.MessageKey);
DependencyService.Get<INotificationManager>().ReceiveNotification(title, message);
}
}
yöntemi, CreateNotificationFromIntent
bağımsız değişkenden intent
bildirim verilerini ayıklar AndroidNotificationManager
ve yöntemini kullanarak ReceiveNotification
öğesine sağlar. CreateNotificationFromIntent
yöntemi hem yönteminden hem de OnCreate
yönteminden çağrılırOnNewIntent
:
- Uygulama bildirim verileriyle başlatıldığında,
Intent
veriler yöntemineOnCreate
geçirilir. - Uygulama zaten ön plandaysa,
Intent
veriler yöntemineOnNewIntent
geçirilir.
Android, bildirimler için birçok gelişmiş seçenek sunar. Daha fazla bilgi için bkz . Xamarin.Android'de bildirimler.
iOS arabirim uygulamasını oluşturma
Xamarin.Forms Uygulamanın iOS'ta bildirim gönderip alması için uygulamanın uygulamasını INotificationManager
sağlaması gerekir.
iOSNotificationManager sınıfını oluşturma
iOSNotificationManager
sınıfı arabirimini INotificationManager
uygular:
using System;
using Foundation;
using UserNotifications;
using Xamarin.Forms;
[assembly: Dependency(typeof(LocalNotifications.iOS.iOSNotificationManager))]
namespace LocalNotifications.iOS
{
public class iOSNotificationManager : INotificationManager
{
int messageId = 0;
bool hasNotificationsPermission;
public event EventHandler NotificationReceived;
public void Initialize()
{
// request the permission to use local notifications
UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert, (approved, err) =>
{
hasNotificationsPermission = approved;
});
}
public void SendNotification(string title, string message, DateTime? notifyTime = null)
{
// EARLY OUT: app doesn't have permissions
if (!hasNotificationsPermission)
{
return;
}
messageId++;
var content = new UNMutableNotificationContent()
{
Title = title,
Subtitle = "",
Body = message,
Badge = 1
};
UNNotificationTrigger trigger;
if (notifyTime != null)
{
// Create a calendar-based trigger.
trigger = UNCalendarNotificationTrigger.CreateTrigger(GetNSDateComponents(notifyTime.Value), false);
}
else
{
// Create a time-based trigger, interval is in seconds and must be greater than 0.
trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(0.25, false);
}
var request = UNNotificationRequest.FromIdentifier(messageId.ToString(), content, trigger);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
throw new Exception($"Failed to schedule notification: {err}");
}
});
}
public void ReceiveNotification(string title, string message)
{
var args = new NotificationEventArgs()
{
Title = title,
Message = message
};
NotificationReceived?.Invoke(null, args);
}
NSDateComponents GetNSDateComponents(DateTime dateTime)
{
return new NSDateComponents
{
Month = dateTime.Month,
Day = dateTime.Day,
Year = dateTime.Year,
Hour = dateTime.Hour,
Minute = dateTime.Minute,
Second = dateTime.Second
};
}
}
}
Ad assembly
alanının üzerindeki özniteliği, arabirim uygulamasını ile DependencyService
kaydederINotificationManager
.
iOS'ta, bildirim zamanlamayı denemeden önce bildirimleri kullanmak için izin istemeniz gerekir. yöntemi, Initialize
yerel bildirimleri kullanmak için yetkilendirme isteğinde bulunur. yöntemi, SendNotification
bildirim oluşturmak ve göndermek için gereken mantığı tanımlar. yöntemi ReceiveNotification
, bir ileti alındığında iOS tarafından çağrılır ve olay işleyicisini çağırır.
Not
SendNotification
yöntemi, bir nesne kullanarak veya tam olarak DateTime
bir UNTimeIntervalNotificationTrigger
nesne kullanarak hemen yerel bir UNCalendarNotificationTrigger
bildirim oluşturur.
iOS'ta gelen bildirimleri işleme
iOS'ta, gelen iletileri işlemek için alt sınıflara UNUserNotificationCenterDelegate
sahip bir temsilci oluşturmanız gerekir. Örnek uygulama bir iOSNotificationReceiver
sınıf tanımlar:
public class iOSNotificationReceiver : UNUserNotificationCenterDelegate
{
public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
ProcessNotification(notification);
completionHandler(UNNotificationPresentationOptions.Alert);
}
void ProcessNotification(UNNotification notification)
{
string title = notification.Request.Content.Title;
string message = notification.Request.Content.Body;
DependencyService.Get<INotificationManager>().ReceiveNotification(title, message);
}
}
Bu sınıf, sınıfının bir örneğini iOSNotificationManager
almak için öğesini DependencyService
kullanır ve yöntemine ReceiveNotification
gelen bildirim verileri sağlar.
SınıfınAppDelegate
, uygulama başlatma sırasında temsilci olarak UNUserNotificationCenter
bir iOSNotificationReceiver
nesne belirtmesi gerekir. Bu, yönteminde FinishedLaunching
gerçekleşir:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
UNUserNotificationCenter.Current.Delegate = new iOSNotificationReceiver();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
iOS, bildirimler için birçok gelişmiş seçenek sunar. Daha fazla bilgi için bkz . Xamarin.iOS'ta Bildirimler.
Uygulamayı test etme
Platform projeleri arabirimin kayıtlı bir uygulamasını içerdiğinde INotificationManager
, uygulama her iki platformda da test edilebilir. Uygulamayı çalıştırın ve bildirim oluşturmak için Bildirim Oluştur düğmelerinden birini tıklatın.
Android'de bildirimler bildirim alanında görünür. Bildirime dokunulduğunda uygulama bildirimi alır ve bir ileti görüntüler:
iOS'ta, gelen bildirimler kullanıcı girişi gerektirmeden uygulama tarafından otomatik olarak alınır. Uygulama bildirimi alır ve bir ileti görüntüler: