Local Notifications

Local notifications are a way to inform users when new data becomes available for your app, even when your app is not running in the foreground. For example, a city builder game may inform a user that construction is complete, and a calendar app might inform the user of an upcoming appointment. 

Unfortunately Android does not provide any functionality to cover this feature. So there are no "local notifications" on the Android platform. But they provide a variety of different ways how to build and display the notifications. So the developer had to handle the scheduling and delivery of its own.  So we decided to implement the delivery system similar to iOS local notifications with TimeInterval Trigger.

Enable Local Notifications API

When you are ready to add local notifications to your application, activate the Local Notifications support, under the Android Editor window. See the image below:

Displaying Notifications

If you want just display notification without scheduling it for delivery in a certain time period, you can use the Notify method, which will instantly post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.

using SA.Android.App;
using SA.Android.SupportV4.App;
...

var builder = new AN_NotificationCompat.Builder();
builder.SetContentText("Text");
builder.SetContentTitle("Title");

var notification = builder.Build();
AN_NotificationManager.Notify(notification);

Providing a custom Icon

In case you don't provide an icon, the default app icons will be used. But you always can provide an original icon for the notifications.

Register your icon inside editor settings as shown on a screenshot below. The icon also should have a specific location in your project. The editor UI will most likely ask you to move the icon to the required location. Just press the move button if it appears.

The icon name must contain only lowercase a-z, 0-9, or underscore.  You can now provide this icon name to a builder. Make sure you only providing a file name without path or extention. See the example below.

using SA.Android.App;
using SA.Android.SupportV4.App;
...

var builder = new AN_NotificationCompat.Builder();
builder.SetContentText("Text");
builder.SetContentTitle("Title")

builder.SetSmallIcon("isn_icon");

var notification = builder.Build();
AN_NotificationManager.Notify(notification);

Providing a custom sound

You may provide the notification sound the same way you do this for an icon. Register your sound inside editor settings as shown on a screenshot below

Move the resource if required. And then feel free to use it with the builder.

using SA.Android.App;
using SA.Android.SupportV4.App;
...

var builder = new AN_NotificationCompat.Builder();
builder.SetContentText("Text");
builder.SetContentTitle("Title")

builder.SetSound("beep");

var notification = builder.Build();
AN_NotificationManager.Notify(notification);

On Android 8 and later, however, the notification sound is part of the channels. If you not using Notification Channels API you have nothing to worry about. Since Android Native plugin will automatically create and configure the channel for your notification. But if you decide to use Notification Channels API you'll need to provide a custom sound for the notification build (for Android versions below 8) and to the notification channel (for Android version >=8). See the example below:

using SA.Android.App;
using SA.Android.SupportV4.App;
...

string channelId = "my_channel_id";
string name = "My Channel Name";
string description = "My Channel Description";
var importance = AN_NotificationManager.Importance.DEFAULT;


AN_NotificationChannel channel = new AN_NotificationChannel(channelId, name, importance);
channel.Description = description;
channel.Sound = "beep";
// you can check if channel exists before re-recreating it
AN_NotificationManager.CreateNotificationChannel(channel);


var builder = new AN_NotificationCompat.Builder();
builder.SetChanelId(channelId);
builder.SetContentText("Text");
builder.SetContentTitle("Title")

builder.SetSound("beep");

var notification = builder.Build();
AN_NotificationManager.Notify(notification);

Scheduling Notifications

Local notifications give you a way to alert the user at times when your app might not be running. You schedule local notifications at the time when your app is running either in the foreground or background. After scheduling a notification, the system takes on the responsibility of delivering the notification to the user at the appropriate time. Your app does not need to be running for the system to deliver the notification. If your app is not running, or if it is in the background, the system displays local notifications directly to the user. The system can alert the user with an alert panel or banner, with a sound, or by badging your app’s icon. If your app provides a notification content app extension, the system can even use your custom interface to alert the user. If your app is in the foreground when a notification arrives, the system gives your app the opportunity to handle the notification internally.

Configuring a Local Notification

The steps for configuring a local notification are as follows:

  1. Create and configure an AN_NotificationCompat.Builder object with the notification details.
  2. Create an AN_AlarmNotificationTrigger object to describe the conditions under which the notification is delivered.
  3. Create an AN_NotificationRequest object with the content and trigger information.
  4. Call the AN_NotificationManager.Schedule method to schedule the notification.

See the code example below:

using SA.Android.App;
using SA.Android.SupportV4.App;
...

var builder = new AN_NotificationCompat.Builder();
builder.SetContentText("Text 2");
builder.SetContentTitle("Title 2");

var trigger = new AN_AlarmNotificationTrigger();
trigger.SetDate(TimeSpan.FromSeconds(5));

// Make sure you provide an unique notification requiest id
// for eatch request you schedule
int id = 1; 
var request = new AN_NotificationRequest(id, builder, trigger);

AN_NotificationManager.Schedule(request);

Responding to Notification

When your app is not running or is in the background, the system automatically delivers local notifications. If your app is running in the foreground, notifications are delivered directly to your app. You can then decide whether to handle the notification quietly or alert the user. To respond to the delivery of notifications, you must subscribe to the OnNotificationClick event.

using SA.Android.App;
...

AN_NotificationManager.OnNotificationClick.AddSafeListener(this, (request) => {
    Debug.Log("request.Identifier: " + request.Identifier);
    Debug.Log("User has opended the local notification request with info: " + JsonUtility.ToJson(request));
});

Handling Notifications When Your App Is in not running

If the user clicked on notification generated by your app, the application will be launched. There is a way to find out for you if your app was launched by notification click. You can use AN_NotificationManager.LastOpenedNotificationRequest as soon as the application is started. If LastOpenedNotificationRequest contains the AN_NotificationRequest object,  means your app was launched with a user clicking the notification. So you can act accordingly.

using SA.Android.App;
...

if(AN_NotificationManager.LastOpenedNotificationRequest != null) {
    Debug.Log("Looks like the app was launched from notifications request: " 
        + JsonUtility.ToJson(AN_NotificationManager.LastOpenedNotificationRequest));
}

Canceling Notifications

It's good practice to cancel all pending notifications once your app is launched and re-schedule new ones. By implemntine this little trick you can make sure that user will not get notifications while your application runing.

There are several methods you can operate.

If you need to remove already delivered notification. You may use the Cancel(int Identifier) method for that purpose:

using SA.Android.App;
...

AN_NotificationManager.Cancel(your_request_id);

Or you can remove all of the delivered notifications with the CancelAll method.

using SA.Android.App;
...

AN_NotificationManager.CancelAll();

When you need to unschedule notification that wasn't yet delivered, use Unschedule(int Identifier) method

using SA.Android.App;
...

AN_NotificationManager.Unschedule(your_request_id);

We also provide UnscheduleAll method, but with certain limitations. The Android platform does not provide scheduling /unscheduled API. So we have to implement it on our own. Android Native will requests id's you schedule using Unity PlayerPrefs, and will use that saved list when you call the UnscheduleAll method. Request Id is saved when Schedule method is called. I will not use PlayerPrefs.Save to not cause any potential hiccups. But you are welcome to add PlayerPrefs.Save after notification is Scheduled, to make sure that plugin 100% will not lose that record, but make sure you not doing this during a gameplay.

Also if you call  PlayerPrefs.DeleteAll it will also a clear list of saved id's used by a plugin, and can potential y prevent some notifications to be unscheduled when UnscheduleAll is called.

 

using SA.Android.App;
...

AN_NotificationManager.UnscheduleAll();