23 Enabling and Using Notifications

This chapter describes how to enable MAF applications to display local notifications as well as register for, and handle, push notification messages.

This chapter includes the following sections:

23.1 Introduction to Notifications

Notifications are audio, visual, or audio-visual signals such as alerts or banners that users receive without user interaction outside of an application, if the application is running. Push notifications are sent from an external source, such as a server, to a registered application on a mobile device, and local notifications are sent by an application and received by itself.

Notifications are signals delivered to the user outside of the regular user interface of a mobile application. These notifications can appear as messages in the form of an alert, or as a banner, depending on the state of the application and user settings. The notifications may be presented visually or as a sound or both.

The following are the two main types of notifications:

  • Push notifications are sent from an external source, such as a server, to an application on a mobile device. When users are notified, they can either launch the application or they can select to ignore the notification in which case the application is not activated.

    Figure 23-1 shows a push notification alert on an iOS-powered device.

    Figure 23-1 Push Notification

    This image is described in the surrounding text

    Applications must register with a notification service to receive push notifications. If the registration succeeds, then the notification service issues a token to the application. The application shares this token with its provider (located on a remote server), and in doing so, enables the provider to send notifications to the application through the notification service. MAF registers on behalf of the application using application-provided registration configuration, described in Enabling Push Notifications. Registration occurs upon every start of the MAF application to ensure a valid token. After a successful registration, MAF shares the token obtained from the platform-specific notification service with the provider. On iOS, the notification service is Apple Push Notification Service (APNs). Google Cloud Messaging (GCM) for Android provides the notification service for applications installed on Android-powered devices.

    A MAF application can receive push notifications regardless of its state: the display of these messages, which can appear even when the application is not in the foreground, depends on the state of the MAF application and the user settings. Table 23-1 describes how the iOS operating system handles push notifications depending on the state of the MAF application.

    Table 23-1 Handling Push Notifications on an iOS-Powered Device

    State Action

    The MAF application is installed, but not running.

    The notification message displays with the registered notification style (none, banner, or alert). When the user taps the message (if its a banner-style notification) or touches the action button (if the message appears as an alert), the MAF application launches, invoking the application notification handlers.

    The MAF application is running in the background.

    The notification message displays with the registered notification style (none, banner, alert). When the user taps the message (if it is a banner-style notification), or touches the action button (if the message appears as an alert), the MAF application launches, invoking the application notification handlers.

    The MAF application is running in the foreground.

    No notification message displays. The application notification handlers are invoked.

    On the iOS and Android platforms, if the application is not running in the foreground, then any push notification messages associated with it are queued in a specific location, such as the iOS Notification Center or the notification drawer on Android-powered devices.

  • Local notifications originate within a mobile application and are received by the same application. The notifications are delivered to the user through standard mechanisms supported by the mobile device platform (for example, banner, sound).

    Using the Local Notification Abstraction API provided by MAF, you can configure the application to raise a notification immediately or schedule a notification for a future date and time. In addition, you can set a repeat pattern for a notification (for example, daily or weekly) as well as cancel a scheduled notification.

    On both the iOS and Android platform, if the MAF application is running in the foreground, the notification is delivered directly to the application without the user interaction. If the application is either running in the background or not running at all, the notification is delivered to the application once the user taps on the notification.

    MAF applications on the Universal Windows Platform do not support local or push notifications.

23.2 Enabling Push Notifications

Enable the PushPlugin plugin in your application and write code that uses the MAF-provided APIs.

You can enable push notifications by performing the following tasks:

  1. Allow the MAF application to receive push notifications by selecting PushPlugin in the Core Plugins section of the Plugins page of the maf-application.xml overview editor, as shown in the following illustration.

    Note:

    By default, a MAF application does not allow push notifications.

    This image is described in the surrounding text
  2. In the application controller project, register an application lifecycle event listener (ALCL) class. See Setting Display Properties for an Application Feature and Using Lifecycle Listeners in MAF Applications .
  3. Implement the oracle.adfmf.application.PushNotificationConfig interface in the ALCL. This interface provides the configuration required to successfully register with the push notification service.

    Override and implement the getNotificationStyle and getSourceAuthorizationId methods of the PushNotificationConfig interface. The getNotificationStyle method enables you to specify the notification styles for which the application registers. The getSourceAuthorizationId method enables you to enter the Google Project Number of the accounts authorized to send messages to the MAF application. For information, see Java API Reference for Oracle Mobile Application Framework.

  4. In the application controller project, create a push notification event listener class (for example, NativePushNotificationListener) that handles push notification events. This class must implement the oracle.adfmf.framework.event.EventListener interface that defines an event listener. For information on the oracle.adfmf.framework.event.EventListener interface, see Java API Reference for Oracle Mobile Application Framework.

    Override and implement the onOpen, onMessage, and onError methods to register for and receive notification events. After a successful registration with the push notification service, MAF calls the onOpen method with the registration token that must be shared with the provider by the application developer. The onError method is invoked if there is an error when registering with the notification service, with the error returned by the push notification service encapsulated as an AdfException.

    MAF calls the onMessage(Event e) method with the notification payload whenever the application receives a notification. The Event object can be used to retrieve useful information about notification payload and the application state. To get the notification payload, use the Event.getPayload method. To get the application state at the time of notification, use the Event.getApplicationState method. For information, see the Event class in Java API Reference for Oracle Mobile Application Framework.

  5. Get an EventSource object in the start method of the ALCL class that represents the source of a native push notification event:
    EventSource evtSource = EventSourceFactory.getEventSource(
            EventSourceFactory.NATIVE_PUSH_NOTIFICATION_REMOTE_EVENT_SOURCE_NAME);
    
  6. Create and add an object of the push notification events listener class to the event source:
    evtSource.addListener(new NativePushNotificationListener());
    

Note:

The MAF for iOS deployment profile displays a Push Notification Environment dropdown list from where you select Production or Development to register your deployed application with the Apple Push Notification service (APNs). The default value is Production. Set this value appropriately for MAF applications that you deploy to iOS. MAF ignores the value that you select if you do not also select the PushPlugin plugin to enable push notifications. For information, see Defining the iOS Build Options.

MAF sample applications called PushDemo and PushServer demonstrate how to handle push notifications. These sample applications are located in the PublicSamples.zip file within the jdev_install/jdeveloper/jdev/extensions/oracle.maf/Samples directory on your development computer.

23.2.1 How to Register a Device for Push Notifications from MCS

Enable push notifications in the MAF application, and then register the device with MCS to receive push notifications from MCS on the device.

To enable a device to receive push notifications from MCS, the device needs to be registered with MCS. This registration is application specific, so you have to register each MAF application with MCS. Before doing this, enable push notifications in your MAF application, as described in Enabling Push Notifications.

Use the following method in MCSPersistenceManager to register the device-application combination with MCS. The following code assumes that your application includes a mobile-persistence-config.properties file that is generated when you use the MAF client data model wizards, described in Creating the Client Data Model in a MAF Application, to create the data model of the MAF application.

public String registerDevice(String token, String appId, String appVersion)

You can call this method from the push notification event listener class that implements the EventListener interface, as described in Enabling Push Notifications.

In this class, the onOpen method is automatically called by MAF and this method passes in the token that you need to register your device. Here is a code sample:

public void onOpen(String token) {
  try {
    String result = new MCSPersistenceManager().registerDevice(token, "com.company.MyMAFApp", "1.0");
  }
  catch (Exception e) {
    throw new AdfException(e.getLocalizedMessage(), AdfException.ERROR);
  }
}

To check whether the registration was successful, click on the Device Registry button in the MCS UI, as shown in Figure 23-2.

Figure 23-2 Device Registry in MCS

The surrounding text describes the image.

As shown in Figure 23-2, the registration includes the username that was used to authenticate against MCS. This means that if you register the device directly in the onOpen method as shown above, the registration uses the anonymous user specified through the anonymous access key in the Connection page, described in Connecting to a REST Service to Create the Client Data Model. This is because the MAF login screen only appears once you try to access a secured feature. Secured feature access takes place after the lifecycle listener start method fired which in turn triggered the onOpen method to fire. This is not a problem as long as you only want to send push notifications to all registered devices. However, if you want to send push notifications to targeted devices based on usernames, you need to postpone the registration until after MAF login. This means that in the onOpen method you need to store the token in an application-scoped variable, and then within the first secured feature you make the call to register the device.

Use the following method in the MCSPersistenceManager class to deregister a device:

public String deregisterDevice(String token, String appId)

23.2.2 What You May Need to Know About the Push Notification Payload

The JSON-formatted push notification payload includes the alert, sound, and badge keys.

MAF respects the following keys for a JSON-formatted payload:

  • alert: the text message shown in the notification prompt.

  • sound: a sound that is played when the notification is received.

  • badge: the number to badge the application icon on iOS.

    Note:

    On Android, the payload can be a JSON object with key-value pairs. The value is always stringified, because the GCM server converts non-string values to strings before sending them to an application. This is not the case with the APNs, which preserves the value types. Refer to the description of the "data" message parameter in Implementing GCM Server in Google Cloud Messaging. This document is available from the Android Developers website at http://developer.android.com/index.html or the Android SDK documentation.

23.3 Managing Local Notifications

Manage local notifications with Java APIs, JavaScript APIs, and the methods of the DeviceFeatures data control provided by MAF.

You can manage local notifications by using the following:

A MAF sample application called LocalNotificationDemo demonstrates how to schedule and handle local notifications. This sample application is located in the PublicSamples.zip file within the jdev_install/jdeveloper/jdev/extensions/oracle.maf/Samples directory on your development computer.

23.3.1 How to Manage Local Notifications Using Java

Use the methods of the oracle.adfmf.framework.api.AdfmfContainerUtilities class to schedule local notifications.

You can schedule local notifications using the following methods of the oracle.adfmf.framework.api.AdfmfContainerUtilities class:

  • addLocalNotification(MafNativeLocalNotificationOptions options). This method returns a String that represents the ID of the notification being scheduled.

    In your Java code, you use this method in a manner similar to the following:

    try {
      // Configure local notification
      MafNativeLocalNotificationOptions options =
                    new MafNativeLocalNotificationOptions();
    
      options.setTitle("some title text");
      options.setAlert("some alert text");
    
      // Set the date in UTC
      options.setDate(LocalDateTime.now(Clock.systemUTC()).plusSeconds(5));
      // Set the notification to repeat every minute
      options.setRepeat(MafNativeLocalNotificationOptions.RepeatInterval.MINUTELY);
      // Set the application badge to be '1' everytime notification is triggered
      options.setBadge(1);
      // Play the default system sound when notification triggers
      options.setSound(MafNativeLocalNotificationOptions.SYSTEM_DEFAULT_SOUND);
      // Vibrate using default system vibration motion when notification triggers
      options.setVibration(
                 MafNativeLocalNotificationOptions.SYSTEM_DEFAULT_VIBRATION);
    
      // Add custom payload that is to be delivered through the local notification
      HashMap<String,Object> payload = new HashMap<String, Object>();
    
      payload.put("somenumber", 1);
      payload.put("somestring", "value2");
      payload.put("someboolean", true);
      options.setPayload(payload);
    
      // Schedule local notification
      String notificationID = AdfmfContainerUtilities.
                              addLocalNotification(options); 
      System.out.println("Notification added successfully. ID is "+notificationID);
    }
    catch(Exception e) {
      System.err.println("There was a problem adding notification");
    }
    

    The notification options' impact on the behavior of your application depends on your target platform. See What You May Need to Know About Local Notification Options and the Application Behavior.

  • cancelLocalNotification(String notificationId). This method returns a String that represents the ID of the successfully canceled notification.

    In your Java code, you use this method in a manner similar to the following:

    try {
      String cancelledNotificationId = AdfmfContainerUtilities.
             cancelLocalNotification("a83b696d-53e7-4242-ab4d-4a771d8d178f");
      System.out.println("Notification successfully canceled"); 
    }
    catch(AdfException e) {
      System.err.println("There was a problem canceling notification");
    }
    

See Java API Reference for Oracle Mobile Application Framework.

23.3.2 How to Manage Local Notifications Using JavaScript

MAF allows you to manage local notifications using JavaScript APIs in the adf.mf.api.localnotification namespace.

The following methods are available:

  • add, defined as follows:

    /**
    * Schedule a local notification
    *
    * @param {Object} options - notification options
    * @param {string} options.title - notification title
    * @param {string} options.alert - notification alert
    * @param {Date} options.date - date at which notification is to be triggered
    * @param {Number} options.badge - application icon is to be badged by this 
    *                                 number when notification is triggered
    * @param {string} options.sound - set it to 'SYSTEM_DEFAULT' to play the
    *                                 default system sound upon a notification
    * @param {string} options.vibration - set it to 'SYSTEM_DEFAULT' for default 
    *                                     system vibration upon a notification
    * @param {Object} options.payload - custom payload to be sent via notification
    * @param {successCallback} scb - success callback
    * @param {errorCallback} ecb - error callback
    */
    adf.mf.api.localnotification.add(options,scb,ecb);
    
    {Object} options : json representing notification options
            {
               // notification title (only Android and iOS 8.2 or later)
               "title" : String,  
               // notification alert text
               "alert" : String,  
               // date-time at which notification should be fired (UTC time zone) 
               "date" : Date,  
               // either 'minutely', 'hourly', 'daily',
               // 'weekly', 'monthly', or 'yearly'
               "repeat" : String,  
               // badge application icon with this number (iOS only)
               "badge" : Number,  
               // if set, the default system sound is played
               "sound" : "SYSTEM_DEFAULT",  
               // if set to "SYSTEM_DEFAULT", the default vibration is 
               // enabled upon an incoming notification (Android only)
               "vibration" : String,  
               // custom JSON data to be passed through the notification
               "payload" : Object,  
            }
    
    
    /**
    * Success Callback
    *
    * @param {Object} request - request
    * @param {Object} response - response
    * @param {string} response.id - id of the scheduled notification
    */
    function scb(request, response) {}
    
    
    /**
    * Error Callback
    *
    * @param {Object} request - request
    * @param {Object} response - response
    */
     function fcb(request, response) {}
    

    The notification options' impact on the behavior of your application depends on your target platform. See What You May Need to Know About Local Notification Options and the Application Behavior.

  • cancel, defined as follows:

    /**
    * Cancel a scheduled local notification
    *
    * @param {string} notificationId - id of the scheduled notification 
    *                                  that needs to be canceled
    * @param {successCallback} scb - success callback
    * @param {errorCallback} ecb - error callback 
    */
    adf.mf.api.localnotification.cancel(notificationId, scb, ecb);
    
    {var} notificationId : id of notification that is to be canceled.
    
    
    /**
    * Success Callback
    *
    * @callback successCallback
    * @param {Object} request - request
    * @param {Object} response - response
    * @param {string} response.id - id of the notification
    */
    
    
    /**
    * Error Callback
    *
    * @callback errorCallback
    * @param {Object} request - request
    * @param {Object} response - response
    */
    

    For information, see JSDoc Reference for Oracle Mobile Application Framework.

23.3.3 How to Manage Local Notifications Using the DeviceFeatures Data Control

You can schedule and cancel a local notification using the addLocalNotification and cancelLocalNotification methods of the DeviceFeatures data control shown in Figure 23-3.

Figure 23-3 Methods of DeviceFeatures Data Control

This image is described in the surrounding text

For information about the DeviceFeatures data control, see Using the DeviceFeatures Data Control.

23.3.4 What You May Need to Know About Local Notification Options and the Application Behavior

The local notification behavior of a MAF application is determined by notifications settings. Review the tabulated local notification options.

Table 23-2 lists the local notification options and describes how setting certain values or failing to set values for each option affects the notification behavior of a MAF application.

Table 23-2 Local Notification Options

Option Value Behavior on iOS Behavior on Android

title

Either:

  • null

  • not specified

The application name is displayed as the notification title.

The notification title in the notification center appears blank.

alert

Either:

  • null

  • not specified

If the notification has other properties specified, such as badge or sound, the notification is delivered to the operating system so that it plays a sound or updates the application icon badge, but the notification is not displayed in the notification center.

If the application is running in the foreground at the time of the notification delivery, the notification is delivered to the application's local notification listener.

The notification is displayed as a banner with a title but without the alert text.

date

Either:

  • null

  • not specified

  • time or date in the past

The notification is triggered immediately.

The notification is triggered immediately.

repeat

Either:

  • null

  • not specified

The notification does not repeat.

The notification does not repeat.

badge

Either:

  • null

  • not specified

  • negative number

The notification does not badge the application icon.

Any existing badge is maintained.

NA Foot 1

badge

0

Any existing badge is removed from the application icon.

NA Foot 2

sound

Other than SYSTEM_DEFAULT_SOUND

An error message is displayed.

The notification does not play sound.

An error message is displayed.

The notification does not play sound.

sound

Not specified

The notification does not play sound.

The notification does not play sound.

vibration

Other than SYSTEM_DEFAULT_VIBRATION

NA Foot 3

An error message is displayed.

The notification does not trigger vibration of a mobile device.

vibration

Not specified

NA Foot 4

The notification does not trigger vibration of a mobile device.

Footnote 1

There is no concept of application badging. The setting is ignored.

Footnote 2

There is no concept of application badging. The setting is ignored.

Footnote 3

You cannot control vibration. The setting is ignored. However, if you specify that the default system sound should be played upon receipt of a notification and if the end user enables the Vibrate on Ring setting on the mobile device, then the device will also vibrate when the notification is received.

Footnote 4

You cannot control vibration. The setting is ignored. However, if you specify that the default system sound should be played upon receipt of a notification and if the end user enables the Vibrate on Ring setting on the mobile device, then the device will also vibrate when the notification is received.

23.4 Determining Application State When MAF Triggers a Notification Event

MAF provides the EventListener interface that you implement to listen for notification events. The onMessage method from this implementation includes an event parameter from where you can retrieve information about the MAF application state when it receives the event by using the Event.getApplicationlicationState() method.

The following example, taken from the LocalNotificationDemo MAF sample application, shows how you can get the notification event payload and determine the state of the MAF application when the notification event arrives.

NativeLocalNotificationListener implements EventListener {
...

    public void onMessage(Event event) {
        ...
              //MAF application state at the time of this notification
        String appState = stringifyAppState(event.getApplicationState());
        String payload = event.getPayload();
        ...
        
        HashMap<String, Object> payloadMap = ((NativeLocalNotificationEvent)event).getPayloadObject();
        ...
        JSONObject jsonPayload = (JSONObject)payloadMap.get("payload");
        ...
        AdfmfJavaUtilities.setELValue("#{applicationScope.notificationAppState}", appState);
        AdfmfJavaUtilities.setELValue("#{applicationScope.notificationPayload}", jsonPayload != null ? jsonPayload.toString() : "");
        AdfmfContainerUtilities.gotoFeature("Notification");
    }
    ...
}

The possible return values from getApplicationState() are:

  • APPLICATION_STATE_UNKNOWN (0) if your MAF application was resident in memory when the notification arrived, but it could not be determined if the MAF application was running in the foreground or background. This case applies only to the iOS platform and the event payload will contain an additional foreground attribute that indicates the correct application state, set to either 1 for foreground or 0 for background. The format of the event payload is similar to:

    {"alert":"My message","foreground":1}
    
  • APPLICATION_STATE_NOT_RUNNING (1) if your MAF application was not resident in memory and the operating system has launched the MAF application to handle the event.

  • APPLICATION_STATE_BACKGROUND (2) if your MAF application was resident in memory when the notification arrived and running in the background.

  • APPLICATION_STATE_FOREGROUND (3) if your MAF application was resident in memory when the notification arrived and running in the foreground.

Use the NativeLocalNotificationEvent class, shown in the above example, that extends oracle.adfmf.framework.event.Event to manage local events. MAF provides the NativePushEvent class that also extends oracle.adfmf.framework.event.Event to manage native push events.

Add your listener in the start() method of the MAF application lifecycle listener, as demonstrated by the following example from the LocalNotificationDemo MAF sample application, to receive events related to local notifications.

public class LifeCycleListenerImpl implements LifeCycleListener
{
...
  public void start()
  {
    // Listen for local notifications
    EventSource evtSource = EventSourceFactory.getEventSource(EventSourceFactory.NATIVE_LOCAL_NOTIFICATION_EVENT_SOURCE_NAME);
    evtSource.addListener(new NativeLocalNotificationListener());
  }
...

For information, see Java API Reference for Oracle Mobile Application Framework and MAF Sample Applications.