716 lines
39 KiB
C
716 lines
39 KiB
C
|
/*
|
||
|
==============================================================================
|
||
|
|
||
|
This file is part of the JUCE library.
|
||
|
Copyright (c) 2020 - Raw Material Software Limited
|
||
|
|
||
|
JUCE is an open source library subject to commercial or open-source
|
||
|
licensing.
|
||
|
|
||
|
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||
|
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||
|
|
||
|
End User License Agreement: www.juce.com/juce-6-licence
|
||
|
Privacy Policy: www.juce.com/juce-privacy-policy
|
||
|
|
||
|
Or: You may also use this code under the terms of the GPL v3 (see
|
||
|
www.gnu.org/licenses).
|
||
|
|
||
|
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||
|
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||
|
DISCLAIMED.
|
||
|
|
||
|
==============================================================================
|
||
|
*/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
namespace juce
|
||
|
{
|
||
|
|
||
|
/** Singleton class responsible for push notifications functionality. Both remote and
|
||
|
local notifications are supported. To get information about notifications,
|
||
|
register a listener on your application startup. It is best to register the
|
||
|
listener as soon as possible, because your application can be launched from
|
||
|
a push notification too.
|
||
|
|
||
|
To send a local notification create an instance of Notification, fill the necessary
|
||
|
fields and call PushNotifications::sendLocalNotification(). When receiving local or
|
||
|
remote notifications, inspect the Notification's fields for notification details.
|
||
|
Bear in mind that some fields will not be available when receiving a remote
|
||
|
notification.
|
||
|
|
||
|
@tags{GUI}
|
||
|
*/
|
||
|
class JUCE_API PushNotifications : private DeletedAtShutdown
|
||
|
{
|
||
|
public:
|
||
|
#ifndef DOXYGEN
|
||
|
JUCE_DECLARE_SINGLETON (PushNotifications, false)
|
||
|
#endif
|
||
|
|
||
|
//==============================================================================
|
||
|
/** Represents a notification that can be sent or received. */
|
||
|
struct Notification
|
||
|
{
|
||
|
Notification() = default;
|
||
|
Notification (const Notification& other);
|
||
|
|
||
|
/** Checks whether a given notification is correctly configured for a given OS. */
|
||
|
bool isValid() const noexcept;
|
||
|
|
||
|
/** Represents an action on a notification that can be presented as a button or a text input.
|
||
|
On Android, each notification has its action specified explicitly, on iOS you configure an
|
||
|
allowed set of actions on startup and pack them into categories (see Settings).
|
||
|
*/
|
||
|
struct Action
|
||
|
{
|
||
|
/** Controls the appearance of this action. */
|
||
|
enum Style
|
||
|
{
|
||
|
button, /**< Show this action as a button. */
|
||
|
text /**< Show this action as a text input field (on Android API 20 or higher is required). */
|
||
|
};
|
||
|
|
||
|
/** @name Common fields */
|
||
|
/**@{*/
|
||
|
Style style = button;
|
||
|
String title; /**< Required. the name of the action displayed to the user. */
|
||
|
String textInputPlaceholder; /**< Optional: placeholder text for text input notification.
|
||
|
Note that it will be ignored if button style is used. */
|
||
|
var parameters; /**< Optional: additional parameters that can be passed. */
|
||
|
/**@}*/
|
||
|
|
||
|
/** @name iOS only fields */
|
||
|
/**@{*/
|
||
|
String identifier; /**< Required: unique identifier. This should be one of the
|
||
|
identifiers set with requestPermissionsWithSettings(). */
|
||
|
bool triggerInBackground = false; /**< Whether the app can process the action in background. */
|
||
|
bool destructive = false; /**< Whether to display the action as destructive. */
|
||
|
String textInputButtonText; /**< Optional: Text displayed on text input notification
|
||
|
button (from iOS 10 only).
|
||
|
Note that it will be ignored if style is set to Style::button. */
|
||
|
/**@}*/
|
||
|
|
||
|
/** @name Android only fields */
|
||
|
/**@{*/
|
||
|
String icon; /**< Optional: name of an icon file (without an extension) to be used for
|
||
|
this action. This must be the name of one of the image
|
||
|
files included into resources when exporting an Android project
|
||
|
(see "Extra Android Raw Resources" setting in Projucer).
|
||
|
Note that not all Android versions support an icon for an action, though
|
||
|
it is recommended to provide it nevertheless. */
|
||
|
|
||
|
StringArray allowedResponses; /**< Optional: a list of possible answers if the answer set is limited.
|
||
|
When left empty, then the user will be able to input any text. */
|
||
|
/**@}*/
|
||
|
};
|
||
|
|
||
|
//==============================================================================
|
||
|
/** @name Common fields */
|
||
|
/**@{*/
|
||
|
|
||
|
String identifier; /**< Required: unique id that can be used to later dismiss the notification
|
||
|
(on iOS available from version 10). */
|
||
|
|
||
|
String title; /**< Required: the title of the notification, usually displayed in the first row. */
|
||
|
String body; /**< Required: the content of the notification, usually displayed in the second row. */
|
||
|
String subtitle; /**< Optional: additional text, that may be displayed e.g. in the third row or in the header
|
||
|
area. Note that on Android, depending on OS version, this may fight for
|
||
|
space with other components of the notification, so use this field
|
||
|
judiciously. On iOS available from version 10. On Android available from API 16. */
|
||
|
|
||
|
String groupId; /**< Optional: allows the OS to visually group, collapse, and expand a set of notifications,
|
||
|
note that OS may automatically group notifications if no groupId is specified.
|
||
|
Available on Android API 20 or above and iOS 10 or above. */
|
||
|
|
||
|
int badgeNumber = 0; /**< Optional: on platforms that support it, can set a number this notification represents. */
|
||
|
URL soundToPlay; /**< Optional: empty when the notification should be silent. When the name is set to
|
||
|
"default_os_sound", then a default sound will be used.
|
||
|
|
||
|
For a custom sound on OSX, set the URL to the name of a sound file (preferably without
|
||
|
an extension) and place the sound file directly in bundle's "Resources" directory (you
|
||
|
can use "Xcode Resource" tickbox in Projucer to achieve that), i.e. it cannot be in a
|
||
|
subdirectory of "Resources" like "Resources/sound". Alternatively, if a sound file
|
||
|
cannot be found in bundle's "Resources" directory, the OS may look for the sound in the
|
||
|
following paths: "~/Library/Sounds", "/Library/Sounds", "/Network/Library/Sounds",
|
||
|
"/System/Library/Sounds".
|
||
|
|
||
|
For a custom sound on iOS, set the URL to a relative path within your bundle, including
|
||
|
file extension. For instance, if your bundle contains "sounds" folder with "my_sound.caf"
|
||
|
file, then the URL should be "sounds/my_sound.caf".
|
||
|
|
||
|
For a custom sound on Android, set URL to the name of a raw resource file
|
||
|
(without an extension) that was included when exporting an Android project in
|
||
|
Projucer (see "Extra Android Raw Resources" setting). */
|
||
|
|
||
|
var properties; /**< Optional: collection of additional properties that may be passed as a dictionary. */
|
||
|
|
||
|
/**@}*/
|
||
|
|
||
|
//==============================================================================
|
||
|
/** @name iOS only fields */
|
||
|
/**@{*/
|
||
|
|
||
|
String category; /**< Required: determines set of actions that will appear (as per setup done
|
||
|
in requestPermissionsWithSettings()). */
|
||
|
double triggerIntervalSec = 0.; /**< Optional: specifies number of seconds before the notification should trigger. */
|
||
|
bool repeat = false; /**< Optional: allows the notification to continuously retrigger after
|
||
|
triggerIntervalSec seconds. Available from iOS 10. */
|
||
|
|
||
|
/**@}*/
|
||
|
|
||
|
//==============================================================================
|
||
|
/** @name Android only fields */
|
||
|
/**@{*/
|
||
|
|
||
|
String icon; /**< Required: name of an icon file (without an extension) to be used for
|
||
|
this notification. This must be the name of one of the image
|
||
|
files included into resources when exporting an Android project
|
||
|
(see "Extra Android Raw Resources" setting in Projucer). */
|
||
|
|
||
|
String channelId; /**< Required for Android API level 26 or above: specifies notification channel id. Refer to
|
||
|
setupChannels(). Ignored on earlier Android versions. */
|
||
|
|
||
|
Image largeIcon; /**< Optional: an additional large icon displayed in the notification content view. */
|
||
|
|
||
|
String tickerText; /**< Optional: ticker text used for accessibility services. */
|
||
|
|
||
|
Array<Action> actions; /**< Optional: actions associated with the notification. Note that the OS may allow only a limited
|
||
|
number of actions to be presented, so always present most important actions first.
|
||
|
Available from Android API 16 or above. */
|
||
|
|
||
|
/** Used to represent a progress of some operation. */
|
||
|
struct Progress
|
||
|
{
|
||
|
int max = 0; /**< Max possible value of a progress. A typical usecase is to set max to 100 and increment
|
||
|
current's value as percentage complete. */
|
||
|
int current = 0; /**< Current progress value, should be from 0 to max. */
|
||
|
bool indeterminate = false; /**< If true, then the progress represents a continuing activity indicator with ongoing
|
||
|
animation and no numeric value. */
|
||
|
};
|
||
|
|
||
|
Progress progress; /**< Optional: set to default (0, 0, false), to disable progress display. */
|
||
|
|
||
|
/** Metadata that can be used by the OS to better handle the notification, depending on its priority. */
|
||
|
enum Type
|
||
|
{
|
||
|
unspecified, /**< Category not set. */
|
||
|
alarm, /**< Alarm or timer. */
|
||
|
call, /**< Incoming voice/video call or similar. */
|
||
|
email, /**< Async message like email. */
|
||
|
error, /**< Error in background operation or authentication status. */
|
||
|
event, /**< Calendar event. */
|
||
|
message, /**< Incoming message (sms, instant message etc.). */
|
||
|
taskProgress, /**< Progress for a long-running background operation. */
|
||
|
promo, /**< Promotion or advertisement. */
|
||
|
recommendation, /**< Specific, single thing related recommendation. */
|
||
|
reminder, /**< User-scheduled reminder. */
|
||
|
service, /**< Running background service. */
|
||
|
social, /**< Social network or sharing update. */
|
||
|
status, /**< Ongoing information about device or contextual status. */
|
||
|
system, /**< System or device status update. */
|
||
|
transport /**< Media transport control for playback. */
|
||
|
};
|
||
|
|
||
|
/** Metadata used as a hint to the OS about the priority of the notification. */
|
||
|
enum Priority
|
||
|
{
|
||
|
veryLow = -2,
|
||
|
low = -1,
|
||
|
medium = 0,
|
||
|
high = 1,
|
||
|
veryHigh = 2
|
||
|
};
|
||
|
|
||
|
String person; /**< Optional: additional metadata used as a hint to OS that a notification is
|
||
|
related to a specific person. Can be useful for instance messaging apps.
|
||
|
Available from Android API 21 or above. */
|
||
|
|
||
|
Type type = unspecified; /**< Optional. Available from Android API 21 or above. */
|
||
|
Priority priority = medium; /**< Optional. Available from Android API 16 or above. */
|
||
|
|
||
|
/** Describes how to show the notification when the screen is locked. Available from Android API 21 or above. */
|
||
|
enum LockScreenAppearance
|
||
|
{
|
||
|
dontShow = -1, /**< The notification is not allowed on the lock screen */
|
||
|
showPartially = 0, /**< Only some information is allowed on the lock screen */
|
||
|
showCompletely = 1 /**< The entire notification is allowed on the lock screen */
|
||
|
};
|
||
|
|
||
|
LockScreenAppearance lockScreenAppearance = showPartially; /**< Optional. */
|
||
|
|
||
|
std::unique_ptr<Notification> publicVersion; /**< Optional: if you set lockScreenAppearance to showPartially,
|
||
|
then you can provide "public version" of your notification
|
||
|
that will be displayed on the lock screen. This way you can
|
||
|
control what information is visible when the screen is locked. */
|
||
|
|
||
|
String groupSortKey; /**< Optional: Used to order notifications within the same group. Available from Android API 20 or above. */
|
||
|
bool groupSummary = false; /**< Optional: if true, then this notification will be a group summary of the group set with groupId.
|
||
|
Available from Android API 20 or above. */
|
||
|
|
||
|
Colour accentColour; /**< Optional: sets accent colour. The default colour will be used if accentColour is not set.
|
||
|
Available from Android API 21 or above. */
|
||
|
Colour ledColour; /**< Optional: Sets the led colour. The hardware will do its best to approximate the colour.
|
||
|
The default colour will be used if ledColour is not set. */
|
||
|
|
||
|
/** Allows to control the time the device's led is on and off. */
|
||
|
struct LedBlinkPattern
|
||
|
{
|
||
|
int msToBeOn = 0; /**< The led will be on for the given number of milliseconds, after which it will turn off. */
|
||
|
int msToBeOff = 0; /**< The led will be off for the given number of milliseconds, after which it will turn on. */
|
||
|
};
|
||
|
|
||
|
LedBlinkPattern ledBlinkPattern; /**< Optional. */
|
||
|
|
||
|
Array<int> vibrationPattern; /**< Optional: sets the vibration pattern in milliseconds. The first value indicates how long
|
||
|
to wait until vibration starts. The second value indicates how long to vibrate. The third
|
||
|
value will say how long to not vibrate and so on. For instance, if the pattern is:
|
||
|
1000, 2000, 3000, 4000 - then one second after receiving a notification the device will
|
||
|
vibrate for two seconds, followed by 3 seconds of no vibration and finally, 4 seconds of
|
||
|
vibration. */
|
||
|
|
||
|
bool shouldAutoCancel = true; /**< Optional: If true, the notification will be automatically cancelled when a user clicks it in the panel. */
|
||
|
|
||
|
bool localOnly = true; /**< Optional: whether or not the notification should bridge to other devices.
|
||
|
Available from Android API 20 or above. */
|
||
|
|
||
|
bool ongoing = false; /**< Optional: If true, then it cannot be dismissed by the user and it must be dismissed manually.
|
||
|
Typically used for ongoing background tasks that the user is actively engaged with. To
|
||
|
dismiss such notification, you need to call removeDeliveredNotification() or
|
||
|
removeAllDeliveredNotifications(). */
|
||
|
|
||
|
bool alertOnlyOnce = false; /**< Optional: Set this flag if you would only like the sound, vibrate and ticker to be played if the notification
|
||
|
is not already showing. */
|
||
|
|
||
|
/** Controls timestamp visibility and format. */
|
||
|
enum TimestampVisibility
|
||
|
{
|
||
|
off, /**< Do not show timestamp. */
|
||
|
normal, /**< Show normal timestamp. */
|
||
|
chronometer, /**< Show chronometer as a stopwatch. Available from Android API 16 or above. */
|
||
|
countDownChronometer /**< Set the chronometer to count down instead of counting up. Available from Android API 24 or above.*/
|
||
|
};
|
||
|
|
||
|
TimestampVisibility timestampVisibility = normal; /**< Optional. */
|
||
|
|
||
|
/** Controls badge icon type to use if a notification is shown as a badge. Available from Android API 26 or above. */
|
||
|
enum BadgeIconType
|
||
|
{
|
||
|
none,
|
||
|
small,
|
||
|
large
|
||
|
};
|
||
|
|
||
|
BadgeIconType badgeIconType = large;
|
||
|
|
||
|
/** Controls sound and vibration behaviour for group notifications. Available from Android API 26 or above. */
|
||
|
enum GroupAlertBehaviour
|
||
|
{
|
||
|
alertAll, /**< both child notifications and group notifications should produce sound and vibration. */
|
||
|
AlertSummary, /**< all child notifications in the group should have no sound nor vibration, even
|
||
|
if corresponding notification channel has sounds and vibrations enabled. */
|
||
|
AlertChildren /**< summary notifications in the group should have no sound nor vibration, even if
|
||
|
corresponding notification channel has sounds and vibrations enabled. */
|
||
|
};
|
||
|
|
||
|
GroupAlertBehaviour groupAlertBehaviour = alertAll;
|
||
|
|
||
|
int timeoutAfterMs = 0; /**< specifies a duration in milliseconds, after which the notification should be
|
||
|
cancelled, if it is not already cancelled. Available from Android API 26 or above. */
|
||
|
/**@}*/
|
||
|
};
|
||
|
|
||
|
|
||
|
//==============================================================================
|
||
|
/** Describes settings we want to use for current device. Note that at the
|
||
|
moment this is only used on iOS and partially on OSX.
|
||
|
|
||
|
On OSX only allow* flags are used and they control remote notifications only.
|
||
|
To control sound, alert and badge settings for local notifications on OSX,
|
||
|
use Notifications settings in System Preferences.
|
||
|
|
||
|
To setup push notifications for current device, provide permissions required,
|
||
|
as well as register categories of notifications you want to support. Each
|
||
|
category needs to have a unique identifier and it can optionally have multiple
|
||
|
actions. Each action also needs to have a unique identifier. The example setup
|
||
|
may look as follows:
|
||
|
|
||
|
@code
|
||
|
|
||
|
using Action = PushNotifications::Settings::Action;
|
||
|
using Category = PushNotifications::Settings::Category;
|
||
|
|
||
|
Action okAction;
|
||
|
okAction.identifier = "okAction";
|
||
|
okAction.title = "OK!";
|
||
|
okAction.style = Action::button;
|
||
|
okAction.triggerInBackground = true;
|
||
|
|
||
|
Action cancelAction;
|
||
|
cancelAction.identifier = "cancelAction";
|
||
|
cancelAction.title = "Cancel";
|
||
|
cancelAction.style = Action::button;
|
||
|
cancelAction.triggerInBackground = true;
|
||
|
cancelAction.destructive = true;
|
||
|
|
||
|
Action textAction;
|
||
|
textAction.identifier = "textAction";
|
||
|
textAction.title = "Enter text";
|
||
|
textAction.style = Action::text;
|
||
|
textAction.triggerInBackground = true;
|
||
|
textAction.destructive = false;
|
||
|
textAction.textInputButtonText = "Ok";
|
||
|
textAction.textInputPlaceholder = "Enter text...";
|
||
|
|
||
|
Category okCategory;
|
||
|
okCategory.identifier = "okCategory";
|
||
|
okCategory.actions = { okAction };
|
||
|
|
||
|
Category okCancelCategory;
|
||
|
okCancelCategory.identifier = "okCancelCategory";
|
||
|
okCancelCategory.actions = { okAction, cancelAction };
|
||
|
|
||
|
Category textCategory;
|
||
|
textCategory.identifier = "textCategory";
|
||
|
textCategory.actions = { textAction };
|
||
|
textCategory.sendDismissAction = true;
|
||
|
|
||
|
PushNotifications::Settings settings;
|
||
|
settings.allowAlert = true;
|
||
|
settings.allowBadge = true;
|
||
|
settings.allowSound = true;
|
||
|
settings.categories = { okCategory, okCancelCategory, textCategory };
|
||
|
|
||
|
@endcode
|
||
|
*/
|
||
|
struct Settings
|
||
|
{
|
||
|
using Action = Notification::Action;
|
||
|
|
||
|
/** Describes a category of a notification. Each category has a unique identifier
|
||
|
and a list of associated actions.
|
||
|
Note that the OS may allow only a limited number of actions to be presented, so
|
||
|
always present most important actions first.
|
||
|
*/
|
||
|
struct Category
|
||
|
{
|
||
|
juce::String identifier; /**< unique identifier */
|
||
|
juce::Array<Action> actions; /**< optional list of actions within this category */
|
||
|
bool sendDismissAction = false; /**< whether dismiss action will be sent to the app (from iOS 10 only) */
|
||
|
};
|
||
|
|
||
|
bool allowSound = false; /**< whether the app should play a sound upon notification */
|
||
|
bool allowAlert = false; /**< whether the app should present an alert upon notification */
|
||
|
bool allowBadge = false; /**< whether the app may badge its icon upon notification */
|
||
|
Array<Category> categories; /**< list of categories the app wants to support */
|
||
|
};
|
||
|
|
||
|
/** Initialises push notifications on current device with the settings provided.
|
||
|
Call this on your application startup and on iOS the first time the application starts,
|
||
|
a user will be presented with a permission request dialog to give push notifications permission.
|
||
|
Once a user responds, Listener::notificationSettingsReceived() will be called so that
|
||
|
you can check what permissions where actually granted. The listener callback will be called
|
||
|
on each subsequent startup too (provided you called requestPermissionsWithSettings() on previous
|
||
|
application run). This way you can check what are current push notifications permissions.
|
||
|
|
||
|
Note that settings are currently only used on iOS. When calling on other platforms, Settings
|
||
|
with no categories and all allow* flags set to true will be received in
|
||
|
Listener::notificationSettingsReceived().
|
||
|
|
||
|
You can also call requestSettingsUsed() to explicitly ask for current settings.
|
||
|
*/
|
||
|
void requestPermissionsWithSettings (const Settings& settings);
|
||
|
|
||
|
/** Sends an asynchronous request to retrieve current settings that are currently in use.
|
||
|
These can be exactly the same as used in requestPermissionsWithSettings(), but depending
|
||
|
on user's subsequent changes in OS settings, the actual current settings may be
|
||
|
different (e.g. user might have later decided to disable sounds).
|
||
|
|
||
|
Note that settings are currently only used on iOS and partially on OSX.
|
||
|
|
||
|
On OSX, only allow* flags are used and they refer to remote notifications only. For
|
||
|
local notifications, refer to System Preferences.
|
||
|
|
||
|
When calling this function on other platforms, Settings with no categories and all allow*
|
||
|
flags set to true will be received in Listener::notificationSettingsReceived().
|
||
|
*/
|
||
|
void requestSettingsUsed();
|
||
|
|
||
|
//==============================================================================
|
||
|
/** Android API level 26 or higher only: Represents notification channel through which
|
||
|
notifications will be sent. Starting from Android API level 26, you should call setupChannels()
|
||
|
at the start of your application, before posting any notifications. Then, when sending notifications,
|
||
|
assign a channel to each created notification.
|
||
|
*/
|
||
|
struct Channel
|
||
|
{
|
||
|
String identifier; /**< Required: Unique channel identifier. */
|
||
|
String name; /**< Required: User facing name of the channel. */
|
||
|
|
||
|
/** Controls how interruptive the notification posted on this channel are. */
|
||
|
enum Importance
|
||
|
{
|
||
|
none,
|
||
|
min,
|
||
|
low,
|
||
|
normal,
|
||
|
high,
|
||
|
max
|
||
|
};
|
||
|
|
||
|
Importance importance = normal; /**< Required. */
|
||
|
Notification::LockScreenAppearance lockScreenAppearance = Notification::showPartially; /**< Optional. */
|
||
|
|
||
|
String description; /**< Optional: user visible description of the channel. */
|
||
|
String groupId; /**< Required: group this channel belongs to (see ChannelGroup). */
|
||
|
Colour ledColour; /**< Optional: sets the led colour for notifications in this channel. */
|
||
|
bool bypassDoNotDisturb = false; /**< Optional: true if notifications in this channel can bypass do not disturb setting. */
|
||
|
bool canShowBadge = false; /**< Optional: true if notifications in this channel can show badges in a Launcher application. */
|
||
|
bool enableLights = false; /**< Optional: true if notifications in this channel should show lights (subject to hardware support). */
|
||
|
bool enableVibration = false; /**< Optional: true if notifications in this channel should trigger vibrations. */
|
||
|
|
||
|
URL soundToPlay; /**< Optional: sound to play in this channel. See Notification::soundToPlay for more info. */
|
||
|
Array<int> vibrationPattern; /**< Optional: vibration pattern for this channel. See Notification::vibrationPattern for more info. */
|
||
|
};
|
||
|
|
||
|
/** Android API level 26 or higher only: represents a channel group. This allows for
|
||
|
visual grouping of corresponding channels in notification settings presented to the user.
|
||
|
At least one channel group has to be specified before notifications can be sent.
|
||
|
*/
|
||
|
struct ChannelGroup
|
||
|
{
|
||
|
String identifier; /**< Required: Unique channel group identifier. */
|
||
|
String name; /**< Required: User visible name of the channel group. */
|
||
|
};
|
||
|
|
||
|
/** Android API level 26 or higher only: configures notification channel groups and channels to be
|
||
|
used in the app. These have to be setup before notifications can be sent on Android API
|
||
|
level 26 or higher.
|
||
|
*/
|
||
|
void setupChannels (const Array<ChannelGroup>& groups, const Array<Channel>& channels);
|
||
|
|
||
|
//==============================================================================
|
||
|
/** iOS only: sends an asynchronous request to retrieve a list of notifications that were
|
||
|
scheduled and not yet delivered.
|
||
|
|
||
|
When the list is retrieved, Listener::pendingLocalNotificationsListReceived() will be called.
|
||
|
*/
|
||
|
void getPendingLocalNotifications() const;
|
||
|
|
||
|
/** Unschedules a pending local notification with a given identifier. Available from iOS 10. */
|
||
|
void removePendingLocalNotification (const String& identifier);
|
||
|
|
||
|
/** Unschedules all pending local notifications. iOS only. */
|
||
|
void removeAllPendingLocalNotifications();
|
||
|
|
||
|
//==============================================================================
|
||
|
/** Checks whether notifications are enabled for given application.
|
||
|
On iOS and OSX this will always return true, use requestSettingsUsed() instead.
|
||
|
*/
|
||
|
bool areNotificationsEnabled() const;
|
||
|
|
||
|
/** On iOS as well as on Android, sends a local notification.
|
||
|
On Android and iOS 10 or above, this will refresh an existing notification
|
||
|
if the same identifier is used as in a notification that was already sent
|
||
|
and not yet responded by a user.
|
||
|
*/
|
||
|
void sendLocalNotification (const Notification& notification);
|
||
|
|
||
|
/** Sends a request for a list of notifications delivered. Such notifications are visible in the
|
||
|
notification area on the device and they are still waiting for user action/response.
|
||
|
When the request is finished Listener::deliveredNotificationsListReceived() will be called.
|
||
|
|
||
|
On iOS, iOS version 10 or higher is required. On Android, API level 18 or higher is required.
|
||
|
For unsupported platforms, Listener::deliveredNotificationsListReceived() will return an empty array.
|
||
|
*/
|
||
|
void getDeliveredNotifications() const;
|
||
|
|
||
|
/** Removes a previously delivered notification. This can be useful for instance when the
|
||
|
information in the notification becomes obsolete.
|
||
|
*/
|
||
|
void removeDeliveredNotification (const String& identifier);
|
||
|
|
||
|
/** Removes all notifications that were delivered. */
|
||
|
void removeAllDeliveredNotifications();
|
||
|
|
||
|
//==============================================================================
|
||
|
/** Retrieves current device token. Note, it is not a good idea to cache this token
|
||
|
because it may change in the meantime. Always call this method to get the current
|
||
|
token value.
|
||
|
*/
|
||
|
String getDeviceToken() const;
|
||
|
|
||
|
/** Android only: allows to subscribe to messages from a specific topic.
|
||
|
So you could for instance subscribe this device to all "sports" topic messages
|
||
|
to receive any remote notifications that have "sports" topic set.
|
||
|
Refer to Firebase documentation for how to send topic messages.
|
||
|
*/
|
||
|
void subscribeToTopic (const String& topic);
|
||
|
|
||
|
/** Android only: allows to remove a topic subscription that was previously added with
|
||
|
subscribeToTopic().
|
||
|
*/
|
||
|
void unsubscribeFromTopic (const String& topic);
|
||
|
|
||
|
/** Android only: sends an upstream message to your app server. The server must implement
|
||
|
XMPP Connection Server protocol (refer to Firebase documentation).
|
||
|
|
||
|
@param serverSenderId Represents the sender. Consult your Firebase project
|
||
|
settings to retrieve the sender id.
|
||
|
|
||
|
@param collapseKey Remote messages with the same collapse key that were not
|
||
|
yet delivered will be collapsed into one, with the
|
||
|
newest message replacing all the previous ones.
|
||
|
Note that there may be a limit of maximum collapse keys
|
||
|
used at the same time and beyond the limit (refer to
|
||
|
Firebase documentation) it is not guaranteed which keys
|
||
|
will be in use by the server.
|
||
|
|
||
|
@param messageId A unique message ID. Used in error callbacks and debugging.
|
||
|
|
||
|
@param messageType Message type.
|
||
|
|
||
|
@param timeToLive TTL in seconds. If 0, the message sending will be attempted
|
||
|
immediately and it will be dropped if the device is not
|
||
|
connected. Otherwise, the message will be queued for the
|
||
|
period specified.
|
||
|
|
||
|
@param additionalData Collection of key-value pairs to be used as an additional
|
||
|
data for the message.
|
||
|
*/
|
||
|
void sendUpstreamMessage (const String& serverSenderId,
|
||
|
const String& collapseKey,
|
||
|
const String& messageId,
|
||
|
const String& messageType,
|
||
|
int timeToLive,
|
||
|
const StringPairArray& additionalData);
|
||
|
|
||
|
//==============================================================================
|
||
|
/** Register a listener (ideally on application startup) to receive information about
|
||
|
notifications received and any callbacks to async functions called.
|
||
|
*/
|
||
|
struct Listener
|
||
|
{
|
||
|
virtual ~Listener() = default;
|
||
|
|
||
|
/** This callback will be called after you call requestSettingsUsed() or
|
||
|
requestPermissionsWithSettings().
|
||
|
|
||
|
Note that settings are currently only used on iOS. When called on other platforms, Settings
|
||
|
with no categories and all allow flags set to true will be received in
|
||
|
Listener::notificationSettingsReceived().
|
||
|
*/
|
||
|
virtual void notificationSettingsReceived (const Settings& settings) { ignoreUnused (settings); }
|
||
|
|
||
|
/** Called when the list of pending notifications, requested by calling
|
||
|
getPendingLocalNotifications() is returned. iOS 10 or above only.
|
||
|
*/
|
||
|
virtual void pendingLocalNotificationsListReceived (const Array<Notification>& notifications) { ignoreUnused (notifications); }
|
||
|
|
||
|
/** This can be called in multiple different situations, depending on the OS and the situation.
|
||
|
|
||
|
On pre iOS 10 device it will be called when a user presses on a notification or when a
|
||
|
notification was received when the app was in the foreground already. On iOS 10 it will be
|
||
|
called when a user presses on a notification
|
||
|
|
||
|
Note: On Android, if remote notification was received while the app was in the background and
|
||
|
then user pressed on it, the notification object received in this callback will contain only
|
||
|
"properties" member set. Hence, if you want to know what was the notification title, content
|
||
|
etc, you need to set them as additional properties, so that you will be able to restore them
|
||
|
from "properties" dictionary.
|
||
|
|
||
|
Note you can receive this callback on startup, if the application was launched from a notification.
|
||
|
*/
|
||
|
virtual void handleNotification (bool isLocalNotification, const Notification& notification) { ignoreUnused (isLocalNotification); ignoreUnused (notification); }
|
||
|
|
||
|
/** This can be called when a user performs some action on the notification such as
|
||
|
pressing on an action button or responding with a text input.
|
||
|
Note that pressing on a notification area, i.e. not on an action button is not considered
|
||
|
to be an action, and hence receivedNotification() will be called in that case.
|
||
|
|
||
|
Note you can receive this callback on startup, if the application was launched from a notification's action.
|
||
|
|
||
|
@param isLocalNotification If the notification is local
|
||
|
@param notification The notification
|
||
|
@param actionIdentifier A String identifying the action
|
||
|
@param optionalResponse Text response a user inputs for notifications with a text input.
|
||
|
Empty for notifications without a text input option.
|
||
|
|
||
|
*/
|
||
|
virtual void handleNotificationAction (bool isLocalNotification,
|
||
|
const Notification& notification,
|
||
|
const String& actionIdentifier,
|
||
|
const String& optionalResponse)
|
||
|
{
|
||
|
ignoreUnused (isLocalNotification);
|
||
|
ignoreUnused (notification);
|
||
|
ignoreUnused (actionIdentifier);
|
||
|
ignoreUnused (optionalResponse);
|
||
|
}
|
||
|
|
||
|
/** For iOS10 and Android, this can be also called when a user dismissed the notification before
|
||
|
responding to it.
|
||
|
*/
|
||
|
virtual void localNotificationDismissedByUser (const Notification& notification) { ignoreUnused (notification); }
|
||
|
|
||
|
/** Called after getDeliveredNotifications() request is fulfilled. Returns notifications
|
||
|
that are visible in the notification area on the device and that are still waiting
|
||
|
for a user action/response.
|
||
|
|
||
|
On iOS, iOS version 10 or higher is required. On Android, API level 18 or higher is required.
|
||
|
For unsupported platforms, an empty array will be returned.
|
||
|
*/
|
||
|
virtual void deliveredNotificationsListReceived (const Array<Notification>& notifications) { ignoreUnused (notifications); }
|
||
|
|
||
|
/** Called whenever a token gets refreshed. You should monitor any token updates, because
|
||
|
only the last token that is assigned to device is valid and can be used.
|
||
|
*/
|
||
|
virtual void deviceTokenRefreshed (const String& token) { ignoreUnused (token); }
|
||
|
|
||
|
/** Called when Firebase Cloud Messaging server deletes pending messages. This can happen when
|
||
|
1) too many messages were sent to the server (hint: use collapsible messages).
|
||
|
2) the devices hasn't been online in a long time (refer to Firebase documentation for
|
||
|
the maximum time a message can be stored on FCM before expiring).
|
||
|
*/
|
||
|
virtual void remoteNotificationsDeleted() {}
|
||
|
|
||
|
/** Called when an upstream message sent with PushNotifications::sendUpstreamMessage() has been
|
||
|
sent successfully.
|
||
|
Bear in mind that in may take several minutes or more to receive this callback.
|
||
|
*/
|
||
|
virtual void upstreamMessageSent (const String& messageId) { ignoreUnused (messageId); }
|
||
|
|
||
|
/** Called when there was an error sending an upstream message with
|
||
|
PushNotifications::sendUpstreamMessage().
|
||
|
Bear in mind that in may take several minutes or more to receive this callback.
|
||
|
*/
|
||
|
virtual void upstreamMessageSendingError (const String& messageId, const String& error) { ignoreUnused (messageId); ignoreUnused (error); }
|
||
|
};
|
||
|
|
||
|
void addListener (Listener* l);
|
||
|
void removeListener (Listener* l);
|
||
|
|
||
|
private:
|
||
|
PushNotifications();
|
||
|
~PushNotifications() override;
|
||
|
|
||
|
ListenerList<PushNotifications::Listener> listeners;
|
||
|
|
||
|
#if JUCE_ANDROID
|
||
|
friend bool juce_handleNotificationIntent (void*);
|
||
|
|
||
|
friend struct JuceFirebaseInstanceIdService;
|
||
|
friend struct JuceFirebaseMessagingService;
|
||
|
#endif
|
||
|
|
||
|
#if JUCE_PUSH_NOTIFICATIONS
|
||
|
struct Pimpl;
|
||
|
friend struct Pimpl;
|
||
|
|
||
|
std::unique_ptr<Pimpl> pimpl;
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
} // namespace juce
|