657 lines
30 KiB
C#
657 lines
30 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Android.App;
|
|
using Android.Content;
|
|
using Android.Graphics;
|
|
using Android.Icu.Util;
|
|
using Android.Media;
|
|
using Android.OS;
|
|
using AndroidX.Core.App;
|
|
using Application = Android.App.Application;
|
|
using Calendar = Android.Icu.Util.Calendar;
|
|
|
|
namespace gehGassi.LocalNotifications.Platforms
|
|
{
|
|
public class NotificationService : INotificationService
|
|
{
|
|
/*
|
|
* Read Me
|
|
* https://developer.android.com/reference/android/app/PendingIntent#FLAG_IMMUTABLE
|
|
* 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.
|
|
*/
|
|
private static PendingIntentFlags pendingIntentFlags = ((int)Build.VERSION.SdkInt >= 31)
|
|
? PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable
|
|
: PendingIntentFlags.UpdateCurrent;
|
|
|
|
private NotificationManager _notificationManager;
|
|
private AlarmManager _alarmManager => Application.Context.GetSystemService(Context.AlarmService) as AlarmManager;
|
|
|
|
private Context CurrentContext;
|
|
|
|
public NotificationService()
|
|
{
|
|
Initialize(Application.Context);
|
|
}
|
|
|
|
public NotificationService(Context context)
|
|
{
|
|
Initialize(context);
|
|
}
|
|
|
|
protected void Initialize(Context context)
|
|
{
|
|
try
|
|
{
|
|
CurrentContext = context;
|
|
|
|
_notificationManager = CurrentContext.GetSystemService(Context.NotificationService) as NotificationManager;
|
|
|
|
if (_notificationManager == null)
|
|
throw new ApplicationException("Notification service not found");
|
|
|
|
CreateDefaultNotificationChannel(context);
|
|
CreateNotificationChannelWithoutSoundAndVibration(context);
|
|
CreateNotificationChannelWithoutSound(context);
|
|
CreateNotificationChannelWithoutVibration(context);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex);
|
|
}
|
|
}
|
|
|
|
private static NotificationTappedEventHandler onNotificationTapped;
|
|
public event NotificationTappedEventHandler OnNotificationTapped
|
|
{
|
|
add => onNotificationTapped += value;
|
|
remove => onNotificationTapped -= value;
|
|
}
|
|
|
|
public static void NotificationTapped(Intent intent)
|
|
{
|
|
if (intent?.Extras != null)
|
|
{
|
|
string payload = intent.GetStringExtra(Constants.PAYLOAD);
|
|
int notificationId = intent.GetIntExtra(Constants.NOTIFICATION_ID, Constants.NOTIFICATION_ID_NOT_FOUND);
|
|
|
|
// do nothing
|
|
if (notificationId == Constants.NOTIFICATION_ID_NOT_FOUND)
|
|
return;
|
|
|
|
var args = new NotificationEventArgs()
|
|
{
|
|
NotificationId = notificationId,
|
|
Payload = payload,
|
|
IsLocal = true
|
|
};
|
|
|
|
onNotificationTapped?.Invoke(args);
|
|
}
|
|
}
|
|
|
|
private static NotificationReceivedEventHandler onNotificationReceived;
|
|
public event NotificationReceivedEventHandler OnNotificationReceived
|
|
{
|
|
add => onNotificationReceived += value;
|
|
remove => onNotificationReceived -= value;
|
|
}
|
|
|
|
public static void NotificationReceived(int notificationId, string payload)
|
|
{
|
|
var args = new NotificationEventArgs()
|
|
{
|
|
NotificationId = notificationId,
|
|
Payload = payload,
|
|
IsLocal = true
|
|
};
|
|
|
|
onNotificationReceived?.Invoke(args);
|
|
}
|
|
|
|
public async Task<List<NotificationRequest>> GetPendingNotificationRequestsAsync()
|
|
=> await LoadScheduledNotificationsAsync(CurrentContext);
|
|
|
|
public async Task CancelAsync(int notificationId)
|
|
=> await CancelNotificationAsync(notificationId);
|
|
|
|
public async Task CancelAllAsync()
|
|
=> await CancelAllNotificationsAsync();
|
|
|
|
public async Task ShowAsync(int notificationId, string title, string description, string payload, AndroidOptions androidOptions = null, IosOptions iOSOptions = null)
|
|
{
|
|
if (androidOptions == null)
|
|
androidOptions = new AndroidOptions();
|
|
|
|
NotificationRequest notificationRequest = new NotificationRequest()
|
|
{
|
|
NotificationId = notificationId,
|
|
Title = title,
|
|
Description = description,
|
|
Payload = payload,
|
|
Android = androidOptions
|
|
};
|
|
|
|
await ShowNotificationAsync(CurrentContext, notificationRequest);
|
|
}
|
|
|
|
public async Task ShowHourlyAsync(int notificationId, string title, string description, Time time, string payload, AndroidOptions androidOptions = null, IosOptions iOSOptions = null)
|
|
=> await RepeatAsync(notificationId, title, description, Day.None, time, NotificationRepeat.Hourly, payload, androidOptions);
|
|
|
|
public async Task ShowDailyAsync(int notificationId, string title, string description, Time time, string payload, AndroidOptions androidOptions = null, IosOptions iOSOptions = null)
|
|
=> await RepeatAsync(notificationId, title, description, Day.None, time, NotificationRepeat.Daily, payload, androidOptions);
|
|
|
|
public async Task ShowWeeklyAsync(int notificationId, string title, string description, Day weekDay, Time time, string payload, AndroidOptions androidOptions = null, IosOptions iOSOptions = null)
|
|
=> await RepeatAsync(notificationId, title, description, weekDay, time, NotificationRepeat.Weekly, payload, androidOptions);
|
|
|
|
public async Task ScheduleAsync(int notificationId, string title, string description, DateTime dateTime, string payload, AndroidOptions androidOptions = null, IosOptions iOSOptions = null)
|
|
{
|
|
//NotityTime a.k.a dateTime / scheduletime
|
|
androidOptions ??= new AndroidOptions();
|
|
|
|
//To Epoch timestamp
|
|
var notifyTimeSinceEpoch = dateTime.GetMilliSecondsSinceEpoch();
|
|
|
|
NotificationRequest notificationRequest = new NotificationRequest()
|
|
{
|
|
NotificationId = notificationId,
|
|
Title = title,
|
|
Description = description,
|
|
NotifyTime = dateTime,
|
|
NotifyTimeSinceEpoch = notifyTimeSinceEpoch,
|
|
Payload = payload,
|
|
Android = androidOptions
|
|
};
|
|
|
|
await ScheduleNotificationAsync(CurrentContext, notificationRequest, true);
|
|
}
|
|
|
|
#region private
|
|
|
|
public async Task ShowNotificationAsync(Context context, NotificationRequest notificationRequest)
|
|
{
|
|
await Task.Delay(1);
|
|
Notification notification = CreateNotification(context, notificationRequest);
|
|
var notificationManager = NotificationManager.FromContext(Application.Context);
|
|
notificationManager.Notify(notificationRequest.NotificationId, notification);
|
|
|
|
var args = new NotificationEventArgs()
|
|
{
|
|
NotificationId = notificationRequest.NotificationId,
|
|
Payload = notificationRequest.Payload,
|
|
IsLocal = true
|
|
};
|
|
onNotificationReceived?.Invoke(args);
|
|
}
|
|
|
|
public Notification CreateNotification(Context context, NotificationRequest notificationRequest)
|
|
{
|
|
//CreateNotificationChannel();
|
|
|
|
var notificationIntent = Application.Context.PackageManager?.GetLaunchIntentForPackage(Application.Context.PackageName ?? string.Empty);
|
|
if (notificationIntent is null)
|
|
throw new Exception("NotificationIntent is null");
|
|
|
|
notificationIntent.SetFlags(ActivityFlags.SingleTop);
|
|
notificationIntent.PutExtra(Constants.PAYLOAD, notificationRequest.Payload);
|
|
notificationIntent.PutExtra(Constants.NOTIFICATION_ID, notificationRequest.NotificationId);
|
|
PendingIntent pendingIntent = PendingIntent.GetActivity(context, notificationRequest.NotificationId, notificationIntent, pendingIntentFlags);
|
|
|
|
var builder = new NotificationCompat.Builder(context, notificationRequest.Android.ChannelId)
|
|
.SetContentTitle(notificationRequest.Title)
|
|
.SetContentText(notificationRequest.Description)
|
|
.SetStyle(new NotificationCompat.BigTextStyle().BigText(notificationRequest.Description))
|
|
//.SetNumber(notificationRequest.BadgeNumber)
|
|
.SetAutoCancel(notificationRequest.Android.AutoCancel)
|
|
.SetOngoing(notificationRequest.Android.OnGoing)
|
|
.SetDefaults((int)NotificationDefaults.All)// | (int)NotificationDefaults.Vibrate)
|
|
.SetContentIntent(pendingIntent);
|
|
|
|
|
|
|
|
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
|
|
{
|
|
builder.SetPriority((int)notificationRequest.Android.Priority);
|
|
}
|
|
|
|
if (notificationRequest.Android.PlaySound)
|
|
{
|
|
var soundUri = GetSoundUri(notificationRequest.Android.Sound);
|
|
if (soundUri != null)
|
|
builder.SetSound(soundUri);
|
|
else
|
|
builder.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification));
|
|
}
|
|
|
|
if (notificationRequest.Android.EnableVibration)
|
|
{
|
|
if (notificationRequest.Android.VibrationPatern != null)
|
|
builder.SetVibrate(notificationRequest.Android.VibrationPatern);
|
|
}
|
|
|
|
if (notificationRequest.Android.Color.HasValue)
|
|
builder.SetColor(notificationRequest.Android.Color.Value);
|
|
|
|
builder.SetSmallIcon(GetIcon(notificationRequest.Android.IconName));
|
|
|
|
//https://stackoverflow.com/questions/33913952/android-notification-is-not-showing-colour-icon-in-marshmallow
|
|
if (Build.VERSION.SdkInt == BuildVersionCodes.M)
|
|
{
|
|
builder.SetLargeIcon(GetIconBitmap(notificationRequest.Android.IconName, context));
|
|
builder.SetSmallIcon(Android.Resource.Color.Transparent);
|
|
builder.SetContentTitle($"HR.To : {notificationRequest.Title}");
|
|
}
|
|
|
|
if (notificationRequest.Android.TimeoutAfter.HasValue)
|
|
builder.SetTimeoutAfter((long)notificationRequest.Android.TimeoutAfter.Value.TotalMilliseconds);
|
|
|
|
//TODO ProgressBar
|
|
|
|
var notification = builder.Build();
|
|
return notification;
|
|
}
|
|
|
|
private async Task RepeatAsync(int notificationId, string title, string description, Day weekDay, Time time, NotificationRepeat repeatInterval, string payload, AndroidOptions androidOptions = null, IosOptions iOSOptions = null)
|
|
{
|
|
androidOptions ??= new AndroidOptions();
|
|
|
|
NotificationRequest notificationRequest = new NotificationRequest()
|
|
{
|
|
NotificationId = notificationId,
|
|
Title = title,
|
|
Description = description,
|
|
CalledAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
|
RepeatInterval = repeatInterval,
|
|
Repeats = true,
|
|
Time = time,
|
|
WeekDay = weekDay,
|
|
Payload = payload,
|
|
Android = androidOptions
|
|
};
|
|
|
|
await RepeatNotificationAsync(CurrentContext, notificationRequest, true);
|
|
}
|
|
|
|
private async Task CancelNotificationAsync(int notificationId)
|
|
{
|
|
#if ANDROID
|
|
if (!OperatingSystem.IsAndroidVersionAtLeast(21))
|
|
return;
|
|
#endif
|
|
Intent intent = new Intent(CurrentContext, typeof(ScheduledNotificationReceiver));
|
|
PendingIntent pendingIntent = PendingIntent.GetBroadcast(CurrentContext, notificationId, intent, pendingIntentFlags);
|
|
_alarmManager.Cancel(pendingIntent);
|
|
|
|
var notificationManager = NotificationManager.FromContext(Application.Context);
|
|
notificationManager.Cancel(notificationId);
|
|
//_notificationManager.Cancel(notificationId);
|
|
await RemoveNotificationFromCacheAsync(CurrentContext, notificationId);
|
|
}
|
|
|
|
private async Task CancelAllNotificationsAsync()
|
|
{
|
|
var notificationManager = NotificationManager.FromContext(Application.Context);
|
|
notificationManager.CancelAll();
|
|
|
|
List<NotificationRequest> scheduledNotifications = await LoadScheduledNotificationsAsync(CurrentContext);
|
|
if (scheduledNotifications == null || scheduledNotifications.Count == 0)
|
|
return;
|
|
|
|
Intent intent = new Intent(CurrentContext, typeof(ScheduledNotificationReceiver));
|
|
foreach (NotificationRequest notification in scheduledNotifications)
|
|
{
|
|
PendingIntent pendingIntent = PendingIntent.GetBroadcast(CurrentContext, notification.NotificationId, intent, pendingIntentFlags);
|
|
_alarmManager.Cancel(pendingIntent);
|
|
}
|
|
|
|
await SaveScheduledNotificationsAsync(CurrentContext, new List<NotificationRequest>());
|
|
}
|
|
|
|
private async Task ScheduleNotificationAsync(Context context, NotificationRequest notificationRequest, bool updateScheduledNotificationsCache)
|
|
{
|
|
string notificationRequestJson = notificationRequest.ToJson();
|
|
Intent notificationIntent = new Intent(Application.Context, typeof(ScheduledNotificationReceiver));
|
|
notificationIntent.PutExtra(Constants.NOTIFICATION_REQUEST, notificationRequestJson);
|
|
PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, notificationRequest.NotificationId, notificationIntent, pendingIntentFlags);
|
|
|
|
var canSetExactAlarm = true;
|
|
if (OperatingSystem.IsAndroidVersionAtLeast(31))
|
|
{
|
|
canSetExactAlarm = _alarmManager?.CanScheduleExactAlarms() ?? false;
|
|
}
|
|
|
|
if (notificationRequest.Android.AllowWhileIdle)
|
|
{
|
|
if(canSetExactAlarm)
|
|
_alarmManager.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, notificationRequest.NotifyTimeSinceEpoch, pendingIntent);
|
|
else
|
|
_alarmManager.SetAndAllowWhileIdle(AlarmType.RtcWakeup, notificationRequest.NotifyTimeSinceEpoch, pendingIntent);
|
|
}
|
|
else
|
|
{
|
|
if(canSetExactAlarm)
|
|
_alarmManager.SetExact(AlarmType.RtcWakeup, notificationRequest.NotifyTimeSinceEpoch, pendingIntent);
|
|
else
|
|
_alarmManager.Set(AlarmType.RtcWakeup, notificationRequest.NotifyTimeSinceEpoch, pendingIntent);
|
|
}
|
|
|
|
if (updateScheduledNotificationsCache)
|
|
await SaveScheduledNotificationAsync(context, notificationRequest);
|
|
}
|
|
|
|
private async Task RepeatNotificationAsync(Context context, NotificationRequest notificationRequest, bool updateScheduledNotificationsCache)
|
|
{
|
|
try
|
|
{
|
|
string notificationRequestJson = notificationRequest.ToJson();
|
|
Intent notificationIntent = new Intent(Application.Context, typeof(ScheduledNotificationReceiver));
|
|
notificationIntent.PutExtra(Constants.NOTIFICATION_REQUEST, notificationRequestJson);
|
|
notificationIntent.PutExtra(Constants.REPEAT, true);
|
|
PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, notificationRequest.NotificationId, notificationIntent, pendingIntentFlags);
|
|
|
|
long repeatInterval = 0;
|
|
|
|
switch (notificationRequest.RepeatInterval)
|
|
{
|
|
case NotificationRepeat.Hourly:
|
|
repeatInterval = 60000 * 60;
|
|
break;
|
|
case NotificationRepeat.Daily:
|
|
repeatInterval = 60000 * 60 * 24;
|
|
break;
|
|
case NotificationRepeat.Weekly:
|
|
repeatInterval = 60000 * 60 * 24 * 7;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
long startTimeMilliSeconds = notificationRequest.CalledAt;
|
|
if (notificationRequest.Time != null)
|
|
{
|
|
Calendar calendar = Calendar.GetInstance(Android.Icu.Util.TimeZone.Default);
|
|
calendar.TimeInMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
calendar.Set(CalendarField.HourOfDay, notificationRequest.Time.Hour);
|
|
calendar.Set(CalendarField.Minute, notificationRequest.Time.Minute);
|
|
calendar.Set(CalendarField.Second, notificationRequest.Time.Second);
|
|
|
|
if (notificationRequest.WeekDay != Day.None)
|
|
calendar.Set(CalendarField.DayOfWeek, (int)notificationRequest.WeekDay);
|
|
|
|
startTimeMilliSeconds = calendar.TimeInMillis;
|
|
}
|
|
|
|
//zukünftige Startzeiten sicherstellen
|
|
long currentTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
while (startTimeMilliSeconds < currentTime)
|
|
startTimeMilliSeconds += repeatInterval;
|
|
|
|
_alarmManager.SetInexactRepeating(AlarmType.RtcWakeup, startTimeMilliSeconds, repeatInterval, pendingIntent);
|
|
|
|
if (updateScheduledNotificationsCache)
|
|
{
|
|
notificationRequest.CalledAt = startTimeMilliSeconds;
|
|
await SaveScheduledNotificationAsync(context, notificationRequest);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("Error in : RepeatNotification");
|
|
Console.WriteLine(ex);
|
|
}
|
|
}
|
|
|
|
public async Task RescheduleNotificationsAsync(Context context)
|
|
{
|
|
List<NotificationRequest> scheduledNotifications = await LoadScheduledNotificationsAsync(context);
|
|
foreach (var notification in scheduledNotifications)
|
|
{
|
|
//Console.WriteLine("Id : " + notification.NotificationId + " | Description : " + notification.Description + " | RepeatInterval : " + notification.RepeatInterval.ToString());
|
|
if (notification.RepeatInterval == NotificationRepeat.None)
|
|
await ScheduleNotificationAsync(context, notification, false);
|
|
else
|
|
await RepeatNotificationAsync(context, notification, false);
|
|
}
|
|
}
|
|
// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement
|
|
private readonly object locker = new object();
|
|
|
|
private async Task<List<NotificationRequest>> LoadScheduledNotificationsAsync(Context context)
|
|
{
|
|
await Task.Delay(1);
|
|
lock (locker)
|
|
{
|
|
List<NotificationRequest> scheduledNotifications = new List<NotificationRequest>();
|
|
using (var sharedPreferences = GetSharedPreferences(context))
|
|
{
|
|
string json = sharedPreferences.GetString(Constants.SCHEDULED_NOTIFICATIONS, null);
|
|
if (json != null)
|
|
scheduledNotifications = json.JsonToListObject<NotificationRequest>();
|
|
|
|
return scheduledNotifications;
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task SaveScheduledNotificationAsync(Context context, NotificationRequest notificationRequest)
|
|
{
|
|
//System.Diagnostics.Debug.WriteLine("SaveScheduledNotification - Start " + DateTime.Now);
|
|
List<NotificationRequest> scheduledNotifications = await LoadScheduledNotificationsAsync(context);
|
|
|
|
int index = scheduledNotifications.FindIndex(x => x.NotificationId == notificationRequest.NotificationId);
|
|
if (index >= 0)
|
|
scheduledNotifications[index] = notificationRequest;
|
|
else
|
|
scheduledNotifications.Add(notificationRequest);
|
|
|
|
await SaveScheduledNotificationsAsync(context, scheduledNotifications);
|
|
|
|
//System.Diagnostics.Debug.WriteLine("SaveScheduledNotification - End " + DateTime.Now);
|
|
}
|
|
|
|
private async Task SaveScheduledNotificationsAsync(Context context, List<NotificationRequest> scheduledNotifications)
|
|
{
|
|
await Task.Delay(1);
|
|
lock (locker)
|
|
{
|
|
string json = scheduledNotifications.ToJson();
|
|
|
|
using (var sharedPreferences = GetSharedPreferences(context))
|
|
{
|
|
using (var editor = sharedPreferences.Edit())
|
|
{
|
|
editor.PutString(Constants.SCHEDULED_NOTIFICATIONS, json);
|
|
|
|
// https://stackoverflow.com/questions/5960678/whats-the-difference-between-commit-and-apply-in-sharedpreferences
|
|
// Unlike Commit(), which writes its preferences out to persistent storage synchronously,
|
|
// Apply() commits its changes to the in-memory SharedPreferences immediately but starts an asynchronous commit to disk and you won't be notified of any failures.
|
|
// Use Apply().
|
|
// It writes the changes to the RAM immediately and waits and writes it to the internal storage(the actual preference file) after.Commit writes the changes synchronously and directly to the file.
|
|
//editor.Apply(); //TODO: Prüfen ob wieder Applay gesetzt werden soll
|
|
var success = editor.Commit();
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
private ISharedPreferences GetSharedPreferences(Context context)
|
|
=> context.GetSharedPreferences(Constants.SCHEDULED_NOTIFICATIONS, FileCreationMode.Private);
|
|
|
|
public async Task RemoveNotificationFromCacheAsync(Context context, int notificationId)
|
|
{
|
|
List<NotificationRequest> scheduledNotifications = await LoadScheduledNotificationsAsync(context);
|
|
|
|
foreach (NotificationRequest notification in scheduledNotifications)
|
|
{
|
|
if (notification.NotificationId == notificationId)
|
|
{
|
|
scheduledNotifications.Remove(notification);
|
|
break;
|
|
}
|
|
}
|
|
|
|
await SaveScheduledNotificationsAsync(context, scheduledNotifications);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create Notification Channel when API >= 26.
|
|
/// Ref : https://stackoverflow.com/questions/29949501/android-show-notification-with-a-popup-on-top-of-any-application
|
|
/// But remember that once you create the channel, you cannot change these settings and the user has final control of whether these behaviors are active. Other option is to uninstall and install application again
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="notificationChannelRequest"></param>
|
|
private void CreateNotificationChannel(Context context, NotificationChannelRequest notificationChannelRequest)
|
|
{
|
|
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
|
|
return;
|
|
|
|
if (notificationChannelRequest == null)
|
|
notificationChannelRequest = new NotificationChannelRequest();
|
|
|
|
if (string.IsNullOrEmpty(notificationChannelRequest.Name))
|
|
notificationChannelRequest.Name = "General";
|
|
|
|
if (string.IsNullOrEmpty(notificationChannelRequest.Id))
|
|
notificationChannelRequest.Id = Constants.DEFAULT_CHANNEL_ID;
|
|
|
|
NotificationManager notificationManager = (NotificationManager)context.GetSystemService(Context.NotificationService);
|
|
|
|
NotificationChannel notificationChannel = notificationManager.GetNotificationChannel(notificationChannelRequest.Id);
|
|
|
|
//update / create hanya saat diperlukan
|
|
//if ((notificationChannel == null && request.ChannelAction == NotificationChannelAction.CreateIfNotExists) ||
|
|
// (notificationChannel != null && request.ChannelAction == NotificationChannelAction.Update))
|
|
{
|
|
notificationChannel = new NotificationChannel(notificationChannelRequest.Id, notificationChannelRequest.Name, notificationChannelRequest.Importance);
|
|
notificationChannel.Description = notificationChannelRequest.Description;
|
|
|
|
if (notificationChannelRequest.PlaySound)
|
|
{
|
|
var soundUri = GetSoundUri(notificationChannelRequest.Sound);
|
|
if (soundUri != null)
|
|
{
|
|
var audioAttributes = new AudioAttributes.Builder().SetUsage(AudioUsageKind.Notification).SetContentType(AudioContentType.Music).Build();
|
|
notificationChannel.SetSound(soundUri, audioAttributes);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
notificationChannel.SetSound(null, null);
|
|
}
|
|
|
|
notificationChannel.EnableVibration(notificationChannelRequest.EnableVibration);
|
|
if (notificationChannelRequest.VibrationPatern != null && notificationChannelRequest.VibrationPatern.Length > 0)
|
|
notificationChannel.SetVibrationPattern(notificationChannelRequest.VibrationPatern);
|
|
|
|
//notificationChannel.LockscreenVisibility = NotificationVisibility.Public
|
|
|
|
notificationChannel.EnableLights(notificationChannelRequest.EnableLights);
|
|
if (notificationChannelRequest.EnableLights && notificationChannelRequest.ColorLight != null)
|
|
notificationChannel.LightColor = notificationChannelRequest.ColorLight;
|
|
|
|
notificationChannel.SetShowBadge(notificationChannelRequest.ShowBadge);
|
|
|
|
notificationManager.CreateNotificationChannel(notificationChannel);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// TODO
|
|
/// </summary>
|
|
private void CreateNotificationChannelGroup()
|
|
{
|
|
|
|
}
|
|
|
|
private Android.Net.Uri GetSoundUri(string soundFileName)
|
|
{
|
|
if (string.IsNullOrEmpty(soundFileName))
|
|
return null;
|
|
|
|
if (soundFileName.Contains("://", StringComparison.InvariantCulture) == false)
|
|
soundFileName = $"{ContentResolver.SchemeAndroidResource}://{Application.Context.PackageName}/raw/{soundFileName}";
|
|
|
|
return Android.Net.Uri.Parse(soundFileName);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="iconName"></param>
|
|
/// <returns></returns>
|
|
private int GetIcon(string iconName)
|
|
{
|
|
var iconId = 0;
|
|
if (!string.IsNullOrEmpty(iconName))
|
|
iconId = Application.Context.Resources.GetIdentifier(iconName, "drawable", Application.Context.PackageName);
|
|
|
|
if (iconId != 0)
|
|
return iconId;
|
|
|
|
iconId = Application.Context.ApplicationInfo.Icon;
|
|
if (iconId == 0)
|
|
iconId = Application.Context.Resources.GetIdentifier("icon", "drawable", Application.Context.PackageName);
|
|
|
|
return iconId;
|
|
}
|
|
|
|
private Bitmap GetIconBitmap(string iconName, Context context)
|
|
{
|
|
var iconId = GetIcon(iconName);
|
|
var bitmap = BitmapFactory.DecodeResource(context.Resources, iconId);
|
|
return bitmap;
|
|
}
|
|
|
|
private void CreateDefaultNotificationChannel(Context context)
|
|
{
|
|
CreateNotificationChannel(context, new NotificationChannelRequest()
|
|
{
|
|
Id = Constants.DEFAULT_CHANNEL_ID,
|
|
Importance = NotificationImportance.High,
|
|
});
|
|
}
|
|
|
|
private void CreateNotificationChannelWithoutSoundAndVibration(Context context)
|
|
{
|
|
CreateNotificationChannel(context, new NotificationChannelRequest()
|
|
{
|
|
Id = Constants.CHANNEL_ID_WITHOUT_SOUND_AND_VIBRATION,
|
|
Name = "NoSoundNoVibration",
|
|
Importance = NotificationImportance.Min,
|
|
EnableVibration = false,
|
|
PlaySound = false,
|
|
});
|
|
}
|
|
|
|
private void CreateNotificationChannelWithoutSound(Context context)
|
|
{
|
|
CreateNotificationChannel(context, new NotificationChannelRequest()
|
|
{
|
|
Id = Constants.CHANNEL_ID_WITHOUT_SOUND,
|
|
Name = "NoSound",
|
|
Importance = NotificationImportance.Min,
|
|
PlaySound = false,
|
|
});
|
|
}
|
|
|
|
private void CreateNotificationChannelWithoutVibration(Context context)
|
|
{
|
|
CreateNotificationChannel(context, new NotificationChannelRequest()
|
|
{
|
|
Id = Constants.CHANNEL_ID_WITHOUT_VIBRATION,
|
|
Name = "NoVibration",
|
|
Importance = NotificationImportance.Min,
|
|
EnableVibration = false,
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|