Push Notifications

Airship's SDK provides a simple interface for managing push notifications within your Android application.

Enabling User Notifications

The Airship SDK makes a distinction between "user notifications", which can be seen by the user, and other forms of push that allow you to send data to your app silently.

Enabling or disabling user notifications is a preference often best left up to the user, so by default, user notifications are disabled. However they are easily enabled with a single call to the PushManager instance.

Enable user notifications
UAirship.shared().getPushManager().setUserNotificationsEnabled(true);

Notification Channels

 Note

Quiet time, sound, and vibration settings have been superseded by notification channels on Android O and newer devices.

Starting with Android O, each notification must assign a valid notification channel or the notification will not display. The SDK will automatically assign a default channel with the name "Notifications". The default channel can be overridden either in AirshipConfigOptions or by setting it directly on the NotificationFactory . The notification channel can also be set per message by specifying the channel's ID in the Push API.

Creating custom notification channels
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

NotificationChannel channel = new NotificationChannel("customChannel",
        context.getString(R.string.custom_channel_name,
        NotificationManager.IMPORTANCE_DEFAULT);

notificationManager.createNotificationChannel(channel);

// Either set the default channel in the airship config or directly
// on the notification factory:
UAirship.shared()
        .getPushManager()
        .getNotificationFactory()
        .setNotificationChannel("customChannel");

Listening For Events

To listen for push and registration events generated by the Airship SDK, extend the AirshipReceiver .

Sample AirshipReceiver
public class SampleAirshipReceiver extends AirshipReceiver {

    private static final String TAG = "SampleAirshipReceiver";

    @Override
    protected void onChannelCreated(@NonNull Context context, @NonNull String channelId) {
        Log.i(TAG, "Channel created. Channel Id:" + channelId + ".");
    }

    @Override
    protected void onChannelUpdated(@NonNull Context context, @NonNull String channelId) {
        Log.i(TAG, "Channel updated. Channel Id:" + channelId + ".");
    }

    @Override
    protected void onChannelRegistrationFailed(Context context) {
        Log.i(TAG, "Channel registration failed.");
    }

    @Override
    protected void onPushReceived(@NonNull Context context, @NonNull PushMessage message, boolean notificationPosted) {
        Log.i(TAG, "Received push message. Alert: " + message.getAlert() + ". posted notification: " + notificationPosted);
    }

    @Override
    protected void onNotificationPosted(@NonNull Context context, @NonNull NotificationInfo notificationInfo) {
        Log.i(TAG, "Notification posted. Alert: " + notificationInfo.getMessage().getAlert() + ". NotificationId: " + notificationInfo.getNotificationId());
    }

    @Override
    protected boolean onNotificationOpened(@NonNull Context context, @NonNull NotificationInfo notificationInfo) {
        Log.i(TAG, "Notification opened. Alert: " + notificationInfo.getMessage().getAlert() + ". NotificationId: " + notificationInfo.getNotificationId());

        // Return false here to allow Airship to auto launch the launcher activity
        return false;
    }

    @Override
    protected boolean onNotificationOpened(@NonNull Context context, @NonNull NotificationInfo notificationInfo, @NonNull ActionButtonInfo actionButtonInfo) {
        Log.i(TAG, "Notification action button opened. Button ID: " + actionButtonInfo.getButtonId() + ". NotificationId: " + notificationInfo.getNotificationId());

        // Return false here to allow Airship to auto launch the launcher
        // activity for foreground notification action buttons
        return false;
    }

    @Override
    protected void onNotificationDismissed(@NonNull Context context, @NonNull NotificationInfo notificationInfo) {
        Log.i(TAG, "Notification dismissed. Alert: " + notificationInfo.getMessage().getAlert() + ". Notification ID: " + notificationInfo.getNotificationId());
    }
}

AirshipReceiver is a base class that handles parsing the raw intents for the application and provides convenient listener style callbacks. Extend the class and register the receiver in the AndroidManifest.xml.

Register the receiver in the `AndroidManifest.xml`
<receiver android:name=".SampleAirshipReceiver"
          android:exported="false">

    <intent-filter>
        <action android:name="com.urbanairship.push.CHANNEL_UPDATED" />
        <action android:name="com.urbanairship.push.OPENED" />
        <action android:name="com.urbanairship.push.RECEIVED" />
        <action android:name="com.urbanairship.push.DISMISSED" />
        <category android:name="${applicationId}" />
    </intent-filter>
</receiver>

Quiet Time

 Note

Quiet time has been superseded by notification channels on Android O and newer devices. However it is still useful for older devices.

Quiet time disables push notification sounds and prevents the phone from vibrating during the set time frame.

// Set the quiet time from 7:30pm - 7:30am
SimpleDateFormat formatter = new SimpleDateFormat("hh:mm", Locale.US);
Date startDate = formatter.parse("19:30");
Date endDate = formatter.parse("07:30");

UAirship.shared().getPushManager().setQuietTimeInterval(startDate,endDate);

// Enable quiet time
UAirship.shared().getPushManager().setQuietTimeEnabled(true);

Clearing Notifications

Notifications can be cleared manually by using standard Android APIs on the NotificationManager or NotificationManagerCompat classes.

Clear all Notifications
NotificationManagerCompat.from(context).cancelAll();

Customizing Push Notifications

 Note

The DefaultNotificationFactory is the recommended factory as it provides full support for all of the Android push features.

All incoming push notifications are built using a class that extends the NotificationFactory .

The Airship SDK uses the DefaultNotificationFactory . With this factory, the standard Android Notification layout will use the application's title and icon. A default big text style will be applied for all notifications.

Accent color, notification icons, default sound, and default title can all be modified by calling the appropriate setter on any of the NotificationFactory instances.

Common customizations
NotificationFactory factory = UAirship.shared().getPushManager().getNotificationFactory();

// Customize the factory
factory.setTitleId(R.string.app_title);
factory.setColor(ContextCompat.getColor(context, R.color.notification_color));

Custom Notification Factories

Custom notification factories are supported, but may cause some Android Push features to no longer work. Only features that the custom factory implements will be available.

Custom Factory Example
public class CustomNotificationFactory extends NotificationFactory {

    public CustomNotificationFactory(Context context) {
        super(context);
    }

    @Override
    public Notification createNotification(PushMessage message, int notificationId) {
        // do not display a notification if there is not an alert
        if (UAStringUtil.isEmpty(message.getAlert())) {
            return null;
        }

        // Build the notification
        NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext())
                .setContentTitle("Notification title")
                .setContentText(message.getAlert())
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.notification_icon);

        // Notification action buttons
        builder.extend(new ActionsNotificationExtender(getContext(), message, notificationId));

        return builder.build();
    }

    @Override
    public int getNextId(PushMessage pushMessage) {
        return NotificationIdGenerator.nextID();
    }

    /**
    * Checks if the push message requires a long running task. If {@code true}, the push message
    * will be scheduled to process at a later time when the app has more background time. If {@code false},
    * the app has approximately 10 seconds total for {@link #createNotification(PushMessage, int)}
    * and {@link #getNextId(PushMessage)}.
    * <p>
    * Apps that return {@code false} are highly encouraged to add {@code RECEIVE_BOOT_COMPLETED} so
    * the push message will persist between device reboots.
    *
    * @param message The push message.
    * @return {@code true} to require long running task, otherwise {@code false}.
    */
   @Override
   public boolean requiresLongRunningTask(PushMessage message) {
       return false;
   }

}
Register the factory once UAirship is ready
@Override
public void onAirshipReady(UAirship airship) {

    // Create a customized default notification factory
    CustomDefaultNotificationFactory notificationFactory;
    notificationFactory = new CustomDefaultNotificationFactory(UAirship.getApplicationContext());

    // Set the factory on the PushManager
    airship.getPushManager().setNotificationFactory(notificationFactory);
}

Available Notification Factories

The Airship SDK contains several notification factories to help simplify creating custom notifications. Any one of them can be extended.

NotificationFactory
Base factory class. Builds notifications without any default styles.
DefaultNotificationFactory
The default SDK factory. Builds notifications with a default big text style.
CustomLayoutNotificationFactory
Builds custom layout notifications.

Available Notification Extenders

The SDK also provides several notification builder extenders to help support Android Push features.

ActionsNotificationExtender
Supports Android Notification Action Button API features.
PublicNotificationExtender
Supports Public Notification API features.
StyleNotificationExtender
Supports Android style API features.
WearableNotificationExtender
Supports Android Wear API features.

Interactive Notifications

Airship provides a set of standard Interactive Notification types (See: Built-In Interactive Notification Types). It is the type that determines which buttons and corresponding labels will be available when you send a push. See the next section for where to specify that in the push payload. You control what happens when you send the push separately, by tying each button ID to a specific action.

Custom Interactive Notification Types (Notification Action Button Groups)

 Note

Airship reserves category IDs prefixed with ua_. Any custom groups with that prefix will be dropped.

If you want to define a custom Interactive Notification type, you must register a new notification action button group.

Custom NotificationActionButtonGroups are supported by registering the groups with the PushManager right after UAirship.takeOff using the PushManager.addNotificationActionButtonGroup method.

Example
// Define actions for the group
NotificationActionButton hiButtonAction = new NotificationActionButton.Builder("hi")
        .setLabel(R.string.hi)
        .setIcon(R.drawable.your_icon_file)
        .setPerformsInForeground(true)
        .build();

NotificationActionButton byeButtonAction = new NotificationActionButton.Builder("bye")
        .setLabel(R.string.bye)
        .setIcon(R.drawable.your_icon_file)
        .setPerformsInForeground(true)
        .build();

// Define the group
NotificationActionButtonGroup buttonGroup = new NotificationActionButtonGroup.Builder()
        .addNotificationActionButton(hiButtonAction)
        .addNotificationActionButton(byeButtonAction)
        .build();

// Add the custom group
airship.getPushManager().addNotificationActionButtonGroup("custom group", buttonGroup);

Android-Specific Payloads

Android has several features not present in other platforms. These can be specified in the Android override in the notification object.