Client example

NNAClientExample MIDlet uses the Nokia Notifications Client API to register and receive notifications on device. It can be used as a reference to write your own notification MIDlets.

You can download the project files for the MIDlet from the download page.

Prerequisites

You need the following to develop this MIDlet:

  • Nokia Asha SDK 1.0 or newer

Design

The Example MIDlet consists of the following classes:

  • Main—The MIDlet main class.

  • MainView—Implements functionality to use Nokia Notification Client API.

Implementation

Check out the usage of Nokia Notifications Client API in the client example:

  • Importing Nokia Notifications Installer classes

  • Checking and updating Notification Enabler

  • Importing Nokia Notifications API classes

  • Opening the session by specifying Application ID and Service ID

  • Registering the MIDlet to get notifications

  • Retrieving the Notification ID

  • Receiving notifications

  • Unregistering from notification

  • Handling various notification error and state changes.

Importing Nokia Notifications Installer classes

These classes need to be imported for managing the installation of the Notification Enabler:

import com.nokia.notifications.installer.InstallListener;
import com.nokia.notifications.installer.InstallerFactory;
import com.nokia.notifications.NotificationsEnablerInstaller;

Checking and updating Notification Enabler

The Main class implements the com.nokia.notifications.installer.InstallListener. The installForm variable is needed to make the downloading, installation and error handling visible for the user:

public class Main extends  MIDlet implements InstallListener {
Form installForm;

NotificationsEnablerInstaller is responsible for keeping track of updating of the Notification Enabler:

public void startApp() {
.
.
.
// Check the availability of Notification Enabler
NotificationsEnablerInstaller installer = 
InstallerFactory.getInstaller();
Installer.checkAndUpdateNapiEnabler(this, installForm, this);

The installResult call-back method is called for letting the MIDlet know the status of downloading and installation:

// Implements for InstallListener interface
Public void installResult(int result) {
if (InstallerListener.INSTALLATION_OK == result ||
    InstallerListener.ALREADY_EXISTS == result) {
    Display.getDisplay(this).setCurrent(new MainView(this));
    } else {
      installForm.append(new StringItem(“Error”,
        “Installation failed with code “ + result));
    }
}

Importing Nokia Notifications API classes

These import statements declare the Nokia Notifications API interface visible for the code.

import com.nokia.notifications.NotificationError;
import com.nokia.notifications.NotificationException;
import com.nokia.notifications.NotificationInfo;
import com.nokia.notifications.NotificationMessage;
import com.nokia.notifications.NotificationSession;
import com.nokia.notifications.NotificationSessionFactory;
import com.nokia.notifications.NotificationSessionListener;
import com.nokia.notifications.NotificationState;

Opening the session by specifying Application ID and Service ID

In the code below, the default Application ID is "com.example", which can be used to send notifications from the Developer Console to the example client MIDlet.

OpenSession makes the session between the example MIDlet and the Notification Enabler established. This needs to be done before the RegisterApplication method can be called.

try {
    session =
        NotificationSessionFactory.openSession(
            main, // The MIDlet instance
            "example.com", // Service ID (Deprecated)
            "com.example", // Application ID
            this); // NotificationSessionListener
}
catch (NotificationException ne) {
    addLogMessage(ERROR, ne.toString());
}

As an exercise you can replace the default Service ID and Application ID values to try out your own service credentials. You can send push notifications to your MIDlet easily from the Developer Console (only in sandbox environment). When you try out the example MIDlet remember to install the Environment Selector MIDlet, switch the used environment to "Sandbox" and boot the device before you try to send a push notifications..

Registering the MIDlet to get notifications

To register to make the MIDlet receive notifications the registerApplication method must be called. When the session state changes, the control of the execution is moved into the stateChanged method.

try {
    session.registerApplication();
}
catch (NotificationException ne) {
    addLogMessage(ERROR, ne.toString());
}

It is mandatory to call registerApplication method every time when the MIDlet is launched to make the MIDlet able to receive notifications.

Retrieving the Notification ID

Your MIDlet needs to retrieve the Notification ID to be able to tell it to your service. Then your service uses it to address the notifications correctly to your MIDlet. The Notification ID is requested by the client MIDlet and then sent to the service, as shown below.

Note:

Sending the Notification ID to the service takes place outside of the Notifications Server. The Nokia Notifications API does not provide a mechanism to send the Notification ID to the service. To retrieve the Notification ID you need to call getNotificationInformation() method on the session object. It is an asynchronous method call, and infoReceived() call back method is called with Notification ID.

In case of bad network the returned NID may be empty. If that happens, you just have to try again.

try {
    session.getNotificationInformation();
}
catch (NotificationException ne) {
    addLogMessage(ERROR, ne.toString());
}

Notification Enabler calls infoReceived method when the Notification ID becomes available. A way how the Notification ID is sent to the service is up to service developer (you may use for example, an HTTP request).

public void infoReceived(NotificationInfo info) {
    String notificationId =  info.getNotificationId();

    if (notificationId.length() == 0) {
        addLogMessage(ERROR, "Received notification ID is empty!");
    }
    else {
        addLogMessage(NOTIFICATION_ID, notificationId);
        System.out.println("Notification ID :-" + notificationId);
    }

Receiving notifications

Notification Enabler calls messageReceived() method when there is an incoming notification. If the MIDlet is running then this method is called directly without showing the notification banner on notification panel.

public void messageReceived(NotificationMessage message) {
    addLogMessage(NOTIFICATION_MESSAGE, message.getPayload().getData());
}

Unregistering from notification

Calling unregister method makes the MIDlet go into offline state and it cannot receive notifications. unregister() method is an asynchronous method. When execution of it is finished then stateChanged() call back method is called by the Notification Enabler.

Note:

Never call unregister method for your own MIDlet unless you really want that no notifications will be sent/received to/by your MIDlet. It is a good idea to include unregistration call into your MIDlet's settings so that the end-user can decide if he/she wants to receive notifications or not.

try {
    session.unregisterApplication();
}
catch (NotificationException ne) {
    addLogMessage(ERROR, ne.toString());
}

Handling various notification error and state changes

Notification Enabler calls stateChanged() method whenever there is any change in the notification State of Notification Enabler or there is some error condition. The developer must ensure the MIDlet handles all possible state change events and error conditions to provide the best possible user experience for their MIDlets.

public void stateChanged(NotificationState state) {
    switch (state.getSessionState()) {
    case NotificationState.STATE_OFFLINE:
        deleteAll();
        removeCommand(unregisterCommand);
        removeCommand(cancelCommand);
        addCommand(registerCommand);
        addLogMessage(STATUS, "Offline");
        break;
    case NotificationState.STATE_CONNECTING:
        deleteAll();
        removeCommand(registerCommand);
        addCommand(cancelCommand);
        addLogMessage(STATUS, "Connecting");
        break;
    case NotificationState.STATE_ONLINE:
        deleteAll();
        removeCommand(registerCommand);
        removeCommand(cancelCommand);
        addCommand(getIdCommand);
        addCommand(unregisterCommand);
        addLogMessage(STATUS, "Online");
        break;
    default:
        addLogMessage(STATUS, "Unknown");
        break;
    }

    final int error = state.getSessionError();

    if (error != NotificationError.ERROR_NONE) {
        addLogMessage(ERROR, notificationStateErrorCodeToString(error));
    }

All possible error has been described in API reference and developer can debug their MIDlets based on the errors provided by Notification Enabler.

Please note, that not all real life errors can be reproduced on SDK Emulator. However, your MIDlet must still handle those error conditions which may not be occurring on SDK Emulator but can happen on device.

List of errors which are commonly not reproduced on SDK Emulator but happen on real device include:

  • ERROR_CONNECTION_DISABLED_BY_USER

  • ERROR_DISABLED_BY_USER

  • ERROR_NO_NETWORK

private String notificationStateErrorCodeToString(final int errorCode) {
    String errorMessage = null;

    switch (errorCode) {
    case NotificationError.ERROR_APPLICATION_ID_CONFLICT:
        errorMessage = "The Application ID has already been registered by another MIDlet.";
        break;
    case NotificationError.ERROR_APPLICATION_ID_INVALID:
        errorMessage = "The Application ID is either empty or more than 255 characters long.";
        break;
    case NotificationError.ERROR_AUTHENTICATION_FAILED:
        errorMessage = "The device is not able to fetch the authentication details from the Notification server.";
        break;
    case NotificationError.ERROR_CONNECTION_DISABLED_BY_USER:
        errorMessage = "The user has disabled connections like WiFi and cellular network.";
        break;
    case NotificationError.ERROR_DISABLED_BY_USER:
        errorMessage = "The user has disabled  notifications.";
        break;
    case NotificationError.ERROR_NO_NETWORK:
        errorMessage = "The Notification Enabler has lost connection with the Notification server.";
        break;
    case NotificationError.ERROR_NONE:
        errorMessage = "No error.";
        break;
    case NotificationError.ERROR_NOT_ALLOWED:
        errorMessage = "NotificationSession is not in correct state.";
        break;
    case NotificationError.ERROR_NOT_KNOWN:
        errorMessage = "Other Notification error.";
        break;
    case NotificationError.ERROR_NOT_REGISTERED:
        errorMessage = "MIDlet is not registered, but is calling for a function that requires registration.";
        break;
    case NotificationError.ERROR_REGISTER_FAILED:
        errorMessage = "Registration failed because there is not enough space available in the device memory to store the settings.";
        break;
    case NotificationError.ERROR_SERVICE_UNAVAILABLE:
        errorMessage = "Notification Server is not available.";
        break;
    case NotificationError.ERROR_SESSION_CLOSED:
        errorMessage = "NotificationSession function call failed because session was closed.";
        break;
    default:
        errorMessage = "Unknown error.";
        break;
    }

    return errorMessage;
}