Skip to content
This repository was archived by the owner on Apr 29, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Android.Content;

namespace LocalNotifications.Droid
{
[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.Instance.Show(title, message);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,33 @@ public class AndroidNotificationManager : INotificationManager
const string channelId = "default";
const string channelName = "Default";
const string channelDescription = "The default channel for notifications.";
const int pendingIntentId = 0;

public const string TitleKey = "title";
public const string MessageKey = "message";

bool channelInitialized = false;
int messageId = -1;
int messageId = 0;
int pendingIntentId = 0;

NotificationManager manager;

public event EventHandler NotificationReceived;

public static AndroidNotificationManager Instance { get; private set; }

public void Initialize()
{
CreateNotificationChannel();
Instance = this;
}

public int ScheduleNotification(string title, string message)
public void Show(string title, string message)
{
if (!channelInitialized)
{
CreateNotificationChannel();
}

messageId++;

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.OneShot);
PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId++, intent, PendingIntentFlags.UpdateCurrent);

NotificationCompat.Builder builder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetContentIntent(pendingIntent)
Expand All @@ -55,9 +52,31 @@ public int ScheduleNotification(string title, string message)
.SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate);

Notification notification = builder.Build();
manager.Notify(messageId, notification);
manager.Notify(messageId++, notification);
}

return messageId;
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 = GetAlarmManager();
alarmManager.Set(AlarmType.RtcWakeup, triggerTime, pendingIntent);
}
else
{
Show(title, message);
}
}

public void ReceiveNotification(string title, string message)
Expand Down Expand Up @@ -86,5 +105,19 @@ void CreateNotificationChannel()

channelInitialized = true;
}

AlarmManager GetAlarmManager()
{
AlarmManager alarmManager = Android.App.Application.Context.GetSystemService(Context.AlarmService) as AlarmManager;
return alarmManager;
}

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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
<AndroidUseAapt2>true</AndroidUseAapt2>
Expand Down Expand Up @@ -60,6 +59,7 @@
<Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="AlarmHandler.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\AboutResources.txt" />
Expand Down Expand Up @@ -87,7 +87,7 @@
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\LocalNotifications\LocalNotifications.csproj">
<Project>{48AB845E-F987-41F0-B81A-1C178087A374}</Project>
<Project>{A7BE66D7-177D-4188-87A1-E6948B3D1C7C}</Project>
<Name>LocalNotifications</Name>
</ProjectReference>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ void CreateNotificationFromIntent(Intent intent)
{
if (intent?.Extras != null)
{
string title = intent.Extras.GetString(AndroidNotificationManager.TitleKey);
string message = intent.Extras.GetString(AndroidNotificationManager.MessageKey);
string title = intent.GetStringExtra(AndroidNotificationManager.TitleKey);
string message = intent.GetStringExtra(AndroidNotificationManager.MessageKey);

DependencyService.Get<INotificationManager>().ReceiveNotification(title, message);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.localnotifications">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<application android:label="LocalNotifications.Android"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk android:minSdkVersion="21" />
<application android:label="LocalNotifications.Android"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Foundation;
using UserNotifications;
using Xamarin.Forms;

Expand All @@ -7,7 +8,7 @@ namespace LocalNotifications.iOS
{
public class iOSNotificationManager : INotificationManager
{
int messageId = -1;
int messageId = 0;

bool hasNotificationsPermission;

Expand All @@ -22,12 +23,12 @@ public void Initialize()
});
}

public int ScheduleNotification(string title, string message)
public void SendNotification(string title, string message, DateTime? notifyTime = null)
{
// EARLY OUT: app doesn't have permissions
if(!hasNotificationsPermission)
if (!hasNotificationsPermission)
{
return -1;
return;
}

messageId++;
Expand All @@ -38,11 +39,19 @@ public int ScheduleNotification(string title, string message)
Subtitle = "",
Body = message,
Badge = 1
};
};

// Local notifications can be time or location based
// Create a time-based trigger, interval is in seconds and must be greater than 0
var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(0.25, false);
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) =>
Expand All @@ -52,8 +61,6 @@ public int ScheduleNotification(string title, string message)
throw new Exception($"Failed to schedule notification: {err}");
}
});

return messageId;
}

public void ReceiveNotification(string title, string message)
Expand All @@ -65,5 +72,18 @@ public void ReceiveNotification(string title, string 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
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public App()
{
InitializeComponent();

// use the dependency service to get a platform-specific implementation and initialize it
// Use the dependency service to get a platform-specific implementation and initialize it.
DependencyService.Get<INotificationManager>().Initialize();

MainPage = new MainPage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ namespace LocalNotifications
public interface INotificationManager
{
event EventHandler NotificationReceived;

void Initialize();

int ScheduleNotification(string title, string message);

void SendNotification(string title, string message, DateTime? notifyTime = null);
void ReceiveNotification(string title, string message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@
Padding="10">
<StackLayout Margin="0,35,0,0"
x:Name="stackLayout">
<Label Text="Click the button to create a local notification."
<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="OnScheduleClick"/>
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>
</ContentPage>
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,20 @@ public MainPage()
};
}

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.ScheduleNotification(title, message);
notificationManager.SendNotification(title, message, DateTime.Now.AddSeconds(10));
}

void ShowNotification(string title, string message)
Expand Down