Android SDK Setup

How to install the Airship SDK on Android.

Requirements

  • Minimum Android version supported 21+
  • Compile SDK version 33+

SDK Installation

The Airship SDK is split into modules which allow you to choose the push providers and features to be included in your application.

ModuleDescription
urbanairship-coreThe core module. Automatically included in the other modules.
urbanairship-admADM push provider
urbanairship-fcmFCM push provider
urbanairship-hmsHMS push provider
urbanairship-automationIn-App Automation, In-App Messaging, and Landing pages
urbanairship-message-centerMessage Center
urbanairship-preference-centerPreference Center
urbanairship-live-updateLive Updates
urbanairship-feature-flagFeature Flags

Current SDK version: 17.7.3

Example installation

app build.gradle.kts

dependencies {

    val airshipVersion = "17.7.3"
    
    // ADM & FCM push providers
    implementation("com.urbanairship.android:urbanairship-fcm:$airshipVersion")
    implementation("com.urbanairship.android:urbanairship-adm:$airshipVersion")
    
    // In-App Messaging
    implementation("com.urbanairship.android:urbanairship-automation:$airshipVersion")
    
    // Message Center
    implementation("com.urbanairship.android:urbanairship-message-center:$airshipVersion")
}
 Note

All Airship dependencies included in the build.gradle.kts file should all specify the exact same version.

app build.gradle

dependencies {

    def airshipVersion = "17.7.3"
    
    // ADM & FCM push providers
    implementation "com.urbanairship.android:urbanairship-fcm:$airshipVersion"
    implementation "com.urbanairship.android:urbanairship-adm:$airshipVersion"
    
    // In-App Messaging
    implementation "com.urbanairship.android:urbanairship-automation:$airshipVersion"
    
    // Message Center
    implementation "com.urbanairship.android:urbanairship-message-center:$airshipVersion"
}
 Note

All Airship dependencies included in the build.gradle file should all specify the exact same version.

Initialize Airship

The Airship SDK must be initialized before any Receiver, Service, or Activity is created. The recommended way to achieve this is by using the Autopilot class, but it is also possible to call takeOff manually in Application#onCreate.

Setup Autopilot

The Airship SDK will automatically launch and load an Autopilot class that can be used to provide custom Airship config and to customize the Airship instance. Autopilot is the recommended approach to integrating the Airship SDK.

To start, create a new class that extends Autopilot. This class needs to be public and have a default no argument constructor.

Custom Autopilot Example

class SampleAutopilot : Autopilot() {
}
public class SampleAutopilot extends Autopilot {
}

Add metadata within the application entry to the AndroidManifest.xml. The name of the meta-data com.urbanairship.autopilot and the value should be the fully qualified class name.

Register the extended Autopilot class
<application
    android:name="com.example.SampleApp">

    <meta-data android:name="com.urbanairship.autopilot"
        android:value="com.example.SampleAutopilot" />

    <!-- ... -->
</application>

Configuring Airship

The AirshipConfigOptions provides the app credentials and common settings for Airship. To provide an AirshipConfigOptions instance, override the method createAirshipConfigOptions in your autopilot class.

Creating Airship config

class SampleAutopilot : Autopilot() {

    override fun createAirshipConfigOptions(context: Context): AirshipConfigOptions? {
        val builder = AirshipConfigOptions.newBuilder()

        // Set default credentials. Alternatively you can set production and development separately
        builder.setAppKey("YOUR APP KEY")
            .setAppSecret("YOUR APP SECRET")

        // Set site. Either SITE_US or SITE_EU
        builder.setSite(AirshipConfigOptions.SITE_EU)

        // Set Common Notification config
        builder.setNotificationAccentColor(ContextCompat.getColor(context, R.color.accent))
            .setNotificationIcon(R.drawable.ic_notification)
            .setNotificationChannel(NotificationProvider.DEFAULT_NOTIFICATION_CHANNEL)

        // Allowlists. Use * to allow anything
        builder.setUrlAllowList(arrayOf("*"))

        // Other config
        return builder.build()
    }
}
public class SampleAutopilot extends Autopilot {
    
    @Override
    public AirshipConfigOptions createAirshipConfigOptions(@NonNull Context context) {
        AirshipConfigOptions.Builder builder = AirshipConfigOptions.newBuilder();

        // Set default credentials. Alternatively you can set production and development separately
        builder.setAppKey("YOUR APP KEY")
               .setAppSecret("YOUR APP SECRET");

        // Set the site. Either SITE_US or SITE_EU.
        builder.setSite(AirshipConfigOptions.SITE_EU);

        // Set Common Notification config
        builder.setNotificationAccentColor(ContextCompat.getColor(context, R.color.accent))
                .setNotificationIcon(R.drawable.ic_notification)
                .setNotificationChannel(NotificationProvider.DEFAULT_NOTIFICATION_CHANNEL);

        // Allowlists for URLs the SDK can open. Use * to allow anything
        builder.setUrlAllowListScopeOpenUrl(new String[] { "*" });
        
        // Other config

        return builder.build();
    }
}

URL allowlist

 Important

SDK 17+ allows all URLs. After upgrading to SDK 17, you will see an implementation error until you either set your own defaults or accept the Airship default of allowing all URLs.

The UrlAllowList controls which URLs the Airship SDK is able to act on. The SDK divides up usages of URLs into two different scopes:

  • SCOPE_OPEN_URL: Only URLs allowed for this scope can be opened from an action, displayed in landing page, or displayed in an HTML in-app message. Defaults to allowing all URLs if not specified in the config.
  • SCOPE_JAVASCRIPT_INTERFACE: These URLs are checked before the Airship JavaScript interface is injected into the webview. Defaults to any Airship originated URLs.

Allowed URLs should be provided when configuring the Airship Config options.

Valid URL pattern syntax
<pattern> := '*' | <scheme>'://'<host>/<path> | <scheme>'://'<host> | <scheme>':/'<path> | <scheme>':///'<path>
<scheme> := <any char combination, '*' are treated as wild cards>
<host> := '*' | '*.'<any char combination except '/' and '*'> | <any char combination except '/' and '*'>
<path> := <any char combination, '*' are treated as wild cards>

Cloud Site

Airship config will default to the US cloud site. If your application is set up for the EU site, you must set the site on the config options to SITE_EU.

Fallback loading

If no config is returned, Airship will default to loading config from the airshipconfig.properties file located in your application’s assets directory. Config keys are just the field names of the AirshipConfigOptions instance.

Customizing Airship behavior

Airship provides common config options in AirshipConfig, however some more advanced configuration must be set directly on the Airship instance. Custom push handling, deep linking, etc., should be configured during onAirshipReady callback. This will ensure Airship is properly configured before handling any messages.

The onAirshipReady callback will be called on a background thread during Airship init process. Applications should not do any long-running work during this callback, or it might prevent Airship from being ready in time to process a push notification.

Customizing the Airship instance

class SampleAutopilot : Autopilot() {
    // ...

    override fun onAirshipReady(airship: UAirship) {
        // Custom Message Center
        MessageCenter.shared().setOnShowMessageCenterListener { messageId: String? ->
            true
        }
        
        // Notification handling
        airship.pushManager.addPushListener(MyPushListener())
        airship.pushManager.notificationListener = MyNotificationListener()
        
        // etc...
    }
}
public class SampleAutopilot extends Autopilot {

    // ...

    @Override
    public void onAirshipReady(@NonNull UAirship airship) {
        MessageCenter.shared().setOnShowMessageCenterListener(messageId -> {
            return true;
        });
        airship.getPushManager().addPushListener(new MyPushListener());
        airship.getPushManager().setNotificationListener(new MyNotificationListener());
    }
}

FCM setup

  1. Follow FCM Android Setup to configure your Android application to connect to Firebase.

  2. Add the urbanairship-fcm dependency to your application’s build.gradle file:

implementation("com.urbanairship.android:urbanairship-fcm:$airshipVersion")
implementation "com.urbanairship.android:urbanairship-fcm:$airshipVersion"

Custom Firebase applications

By default, the Airship SDK will use the data in google-services.json to configure Firebase Messaging. If your app makes use of multiple Firebase projects, you can instruct the Airship SDK to use a specific named Firebase project for Firebase Cloud Messaging (FCM).

In order to create a secondary Firebase application instance, you’ll need to manually configure FirebaseOptions and initialize your secondary Firebase application. The Firebase application should be initialized before takeOff, or during the onAirshipReady callback.

Initialize the secondary Firebase Application instance

// Manually configure FirebaseOptions for the secondary Firebase Application.
val options = FirebaseOptions.Builder()
        .setProjectId("Your Firebase Project ID")
        .setApplicationId("Your Firebase Application ID")
        .setApiKey("Your Firebase API key")
        .setGcmSenderId("Your GCM Sender ID")
        .build()

// Initialize the secondary Firebase Application.
Firebase.initialize(context, options, "secondary")
// Manually configure FirebaseOptions for the secondary Firebase Application.
FirebaseOptions options = new FirebaseOptions.Builder()
        .setProjectId("Your Firebase Project ID")
        .setApplicationId("Your Firebase Application ID")
        .setApiKey("Your Firebase API key")
        .setGcmSenderId("Your GCM Sender ID")
        .build();

// Initialize the secondary Firebase Application.
FirebaseApp.initializeApp(context, options, "secondary");

Now that you have initialized your secondary Firebase application, you can configure the Airship SDK to use it by setting Firebase app name name in the AirshipConfigOptions instance.

Extending the FirebaseMessagingService

If your application uses its own FirebaseMessagingService or some other third party push provider, you will also need to forward onNewToken and onMessageReceived calls to the Airship SDK.

Custom FirebaseMessagingService

fun onNewToken(token: String) {
    AirshipFirebaseIntegration.processNewToken(getApplicationContext(), token)
}

fun onMessageReceived(remoteMessage: RemoteMessage) {
    AirshipFirebaseIntegration.processMessageSync(getApplicationContext(), message)
}
@Override
public void onNewToken(String token) {
    AirshipFirebaseIntegration.processNewToken(getApplicationContext(), token);
}

@Override
public void onMessageReceived(RemoteMessage message) {
    AirshipFirebaseIntegration.processMessageSync(getApplicationContext(), message);
}

ADM setup

  1. Follow Amazon’s documentation to store your API key as an asset.

  2. Add the urbanairship-adm dependency to your application’s build.gradle file:

implementation("com.urbanairship.android:urbanairship-adm:$airshipVersion")
implementation "com.urbanairship.android:urbanairship-adm:$airshipVersion"

HMS setup

  1. Follow Huawei’s documentation to set up the HMS SDK.

     Note

    Airship requires HMS Core Push SDK 6.3.0.304 or newer.

  2. Add the urbanairship-hms dependency to your application’s build.gradle file:

    implementation("com.urbanairship.android:urbanairship-hms:$airshipVersion")
    implementation "com.urbanairship.android:urbanairship-hms:$airshipVersion"

Extending the HmsMessageService

If your application uses its own HmsMessageService or some other third party push provider, you will also need to forward onNewToken and onMessageReceived calls to the Airship SDK.

Custom HmsMessageService

fun onNewToken(token: String?) {
    AirshipHmsIntegration.processNewToken(getApplicationContext(), token)
}

fun onMessageReceived(remoteMessage: RemoteMessage) {
    AirshipHmsIntegration.processMessageSync(getApplicationContext(), message)
}
@Override
public void onNewToken(@Nullable String token) {
    AirshipHmsIntegration.processNewToken(getApplicationContext(), token);
}

@Override
public void onMessageReceived(RemoteMessage message) {
    AirshipHmsIntegration.processMessageSync(getApplicationContext(), message);
}

Implementation best practices

Make sure to set up logging. Internal logging can be valuable when troubleshooting issues that arise when testing.

Anytime you make any changes or updates to the SDK, test on a development device to ensure your integration was successful. Also make sure analytic information is still flowing to your Airship project before sending the app to production.