Android SDK

    SDK Setup


    Download v2.22.2

    SDK Installation

    Installation with Gradle

    Add the following repository under the allproject/repositores block in your project/build.gradle file.

    123456789
    allprojects {
        ...
        repositories {
            ...
            maven { url "https://sdk-download.airbridge.io/maven" }
            ...
        }
        ...
    }

    If you're using Android Studio Arctic Fox (2020.3.1) or to create your project, or if your repository settings are done within the settings.gradle file, add the following to your project/settings.gradle file under the dependencyResolutionManagement/repositories block.

    123456789
    dependencyResolutionManagement {
        ...
        repositories {
            ...
            maven { url "https://sdk-download.airbridge.io/maven" }
            ...
        }
        ...
    }

    Add the following to the dependencies block in your app/build.gradle file

    12345
    dependencies {
        ...
        implementation "io.airbridge:sdk-android:2.+"
        ...
    }

    Direct Installation with an AAR File

    The Airbridge SDK uses JetBrains' Kotlin and Coroutines libraries for better stability and productivity. Please add following dependency libraries in your project when setting up using an ARR file.

    Library

    Link

    Airbridge SDK

    Download

    JetBrains Java Annotations

    Download

    Kotlin Standard Library

    Download

    Kotlinx Coroutines Core

    Download

    Kotlinx Coroutines Android

    Download

    Airbridge Android SDK requires Kotlin stdlib and Kotlinx coroutines library version 1.4 or higher.

    Project Setup

    Min SDK 16

    Add Permissions

    Please add the following permissions in your AndroidManifest.xml file

    123456
    <manifest ...>
      ...
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      ...
    </manifest>

    Initialization

    Please add the following code under the onCreate method of the Application class file registered in the AndroidManifest.xml file.

    1234567
    @Override
    public void onCreate() {
        super.onCreate();
        AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
            .build();
        Airbridge.init(this, config);
    }

    Attention

    For proper operation, please make sure that the init method is called at the time of onCreate of the Application class.

    You can find YOUR_APP_NAME and YOUR_APP_SDK_TOKEN in the "Airbridge Dashboard → Settings → Tokens" tab.

    Testing the SDK

    Once the basic installation and configuration of the Airbridge SDK is complete, you can test whether it has been correctly setup through the following methods.

    Check in the Airbridge Dashboard

    1. Install and open the app on the device that you want to test

    2. Go to "Airbridge dashboard → Raw Data → App Real-time Logs"

    3. Enter Google Advertising ID of the device in the search box

    Please re-check the guide above if you do not see any install event with your Google Advertising ID

    You can find the Google Advertising ID of a device at Settings → Google → Ads → Your advertising ID.

    Check in LogCat

    Use the following method if you want to use LogCat to see a more detailed log of the app.

    Attention

    Since this method may expose user information, please make sure the method is executed only for the Build.DEBUG case.

    12345
    // Default log level = Log.INFO
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setLogLevel(Log.DEBUG)
        .build();
    Airbridge.init(this, config);


    Dashboard Setup

    The following information must be registered on the [Tracking Link]>[Deep Link] page in your Airbridge dashboard.

    • URI Scheme

    • Package name

    • sha256_cert_fingerprints

    Enter URI Scheme

    Enter the Android URI scheme, including ://, into the URI scheme field. Only lowercase letters, numbers, -, and + are supported.

    Attention

    The URI scheme must be entered differently for the production app, which is the app that has already been released on app stores or is planning to be released, and the test app.

    If the same URI scheme is entered for the production app and test app, the deep link may open an unintended app page.

    Enter package name

    The package name of the production app already released on app stores will be automatically filled.

    The package names of the production app that has not been released on app stores yet and the test app must be entered manually in the Android package name field.

    Register Fingerprint

    Follow the below steps to obtain the sha256_cert_fingerprint.

    1. Prepare the keystorefile that you used to register your app with Google Play Store.

    2. Execute the following command in Linux.

    Shell
    1
    keytool -list -v -keystore my-release-key.keystore

    3. Copy the SHA256value under the Certificate Fingerprints section and paste it under Android sha256_cert_fingerprintsas shown in the picture above.

    Shell
    1234
    Certificate fingerprints:
        MD5:  4C:65:04:52:F0:3F:F8:65:08:D3:71:86:FC:EF:C3:49
        SHA1: C8:BF:B7:B8:94:EA:5D:9D:38:59:FE:99:63:ED:47:B2:D9:5A:4E:CC
        SHA256: B5:EF:4D:F9:DC:95:E6:9B:F3:9A:5E:E9:D6:E0:D8:F6:7B:AB:79:C8:78:67:34:D9:A7:01:AB:6A:86:01:0E:99

    Attention

    Multiple Android sha256_cert_fingerprints can be entered by separating them with commas.

    Project Setup

    Intent Filter Setup

    Follow these steps to setup the intent-filter

    1. Open AndroidManifest.xml

    2. Add the following intent-filterto the activitythat will process the deep link.

    123456789101112131415161718192021222324252627282930
    <activity ...>
        ...
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="http" android:host="YOUR_APP_NAME.abr.ge" />
            <data android:scheme="https" android:host="YOUR_APP_NAME.abr.ge" />
        </intent-filter>
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="http" android:host="YOUR_APP_NAME.airbridge.io" />
            <data android:scheme="https" android:host="YOUR_APP_NAME.airbridge.io" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="YOUR_APP_URI_SCHEME" />
        </intent-filter>
        ...
    </activity>
    • YOUR_APP_NAME.deeplink.page: Airbridge App Links Version 2

    • YOUR_APP_NAME.airbridge.io: Airbridge App Links Version 1

    • YOUR_APP_URI_SCHEME: URI Scheme of the deep link (e.g. abc://)

    Custom Domain Setup

    The deeplink.page or abr.ge domains are available when creating a tracking link at the Airbridge dashboard. Customized URLs such as go.my_company.com/abcd can also be used as tracking links to improve the branding and CTR (Click Through Rate).

    1. Please follow this guide to setup custom domains.

    2. Create a /res/values/airbridge.xml file and edit it as below

    123456
    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:tools="http://schemas.android.com/tools">
        <string-array name="co_ab180_airbridge_custom_domains">
            <item>YOUR_CUSTOM_DOMAIN</item>
        </string-array>
    </resources>

    3. Add the following intent-filterto the activitythat will process the deep link.

    12345678910111213
    <activity ...>
        ...
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="http" android:host="YOUR_CUSTOM_DOMAIN" />
            <data android:scheme="https" android:host="YOUR_CUSTOM_DOMAIN" />
        </intent-filter>
        ...
    </activity>

    Attention

    YOUR_CUSTOM_DOMAIN should match the information in the Airbridge dashboard

    The edit below is needed to process the deep link as defined by the intent-filter above.

    123456789101112131415161718192021222324252627
    @Override
    protected void onResume() {
        super.onResume();
        Airbridge.getDeeplink(getIntent(), new AirbridgeCallback<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                // Process deeplink data
            }
    
            @Override
            public void onFailure(Throwable throwable) {
                // Error
            }
    
            @Override
            public void onComplete() {
                // After process deeplink data
            }
        });
    }
    
    // The code below is required for proper deeplink processing
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
    }

    In the general case of a deferred deep link in Airbridge SDK, the intent-filter automatically calls the corresponding activity and can be processed in the same way as a deep link callback.

    When the corresponding activity is called through an Airbridge deferred deep link, the deferred=true query parameter is also passed on.

    You can use the following method if you do not want the deferred deep link to automatically call an activity, or want to process a specific job with the information obtained through the deferred deep link.

    1234567891011
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setOnDeferredDeeplinkReceiveListener(new OnDeferredDeeplinkReceiveListener() {
            @Override
            public boolean shouldLaunchReceivedDeferredDeeplink(Uri uri) {
                // If you want to open the target activity, please return true otherwise false
                // Default returning value = true
                return true;
            }
        })
        .build();
    Airbridge.init(this, config);

    Click on your URI scheme to test if your deep link has been properly set up in the Airbridge SDK.

    • YOUR_APP_URI_SCHEME://

    The results will show on the "Airbridge dashboard → Raw Data → App Real-time Log" tab if everything is working.

    User Setup


    User Identifier Setup

    To measure the fragmented contributions of users between web and app, Airbridge collects the following user identifier information.

    • User Email: Email address

    • User Phone: Phone number

    • User ID: Unique User ID (The ID value that specifies the user must be the same in both web and mobile)

    • User Alias: Identifiers that can represent users (e.g. loyalty program ID, affiliate integrated ID, etc)

    The user's email and phone numbers are hashed (SHA256) by default and then sent to servers.

    You can set the user identifier as below for the SDK.

    1234567891011
    // Automatically hashed on client side using SHA256
    // Can turn off hashing feature with special flag
    Airbridge.getCurrentUser().setEmail("testID@ab180.co");
    Airbridge.getCurrentUser().setPhone("821012341234");
    
    // Does not hash 
    Airbridge.getCurrentUser().setId("testID");
    Airbridge.getCurrentUser().setAlias("key", "value");
    
    // Clear user data
    Airbridge.expireUser()

    Name

    Description

    Limitations

    Email

    User email

    Hashed by default
    (SHA256, can be disabled)

    Phone

    User phone number

    Hashed by default
    (SHA256, can be disabled)

    Id

    User ID

    -

    Alias

    User alias

    - Maximum 10 aliases
    - "key"type is String, maximum 128 characters
    - "key"must satisfy ^[a-z_][a-z0-9_]*$regex
    -"value"type is String, maximum 1024 characters

    Once the user identifier has been setup, all events will be forwarded with the corresponding identity information.

    User Attributes Setup

    Additional user attributes can be used for more accurate Multi-Touch Attribution (MTA) analyses, additional internal data analysis, and linking third-party solutions.

    1
    Airbridge.getCurrentUser().setAttribute("key", "value");

    Name

    Description

    Limitations

    setAttribute

    User attribute

    - Maximum 100 attributes
    - "key" type is string, maximum 128 characters
    - "key" must satisfy ^[a-z_][a-z0-9_]*$regex
    - "value" type is primitive or string
    - Maximum 1024 characters when "value" is string

    Test User Information Setup

    Check your user information settings at "Airbridge Dashboard → Raw Data → App Real-time Log".

    Device Setup


    Setup Device Alias

    Setup a device alias through the Airbridge SDK. The alias will be sustained even after the app closes, unless otherwise deleted.

    123
    Airbridge.setDeviceAlias("ADD_YOUR_KEY", "AND_YOUR_VALUE");
    Airbridge.removeDeviceAlias("DELETE_THIS_KEY");
    Airbridge.clearDeviceAlias();

    Method

    Description

    setDeviceAlias(key: String, value: String)

    Add the key value pair to the device identifier.

    removeDeviceAlias(key: String)

    Delete the corresponding device alias.

    clearDeviceAlias()

    Delete all device aliases.

    Event Setup


    All events called by the Airbridge SDK can be sent with the following fields.

    Name

    Type

    Description

    EventCategory

    String

    Name of the event

    Required

    event_action

    String

    Event attribute 1

    event_label

    String

    Event attribute 2

    eventValue

    Number

    Event attribute value

    eventAttributes

    Map<String, Object>

    Custom attributes

    semanticAttributes

    Semantic attributes class

    Semantic attributes

    Below is an example of how you can send a standard event using the Airbridge SDK.

    12345
    Number eventValue = 10;
    Map<String, Object> eventAttributes = new HashMap<String, Object>();
    SemanticAttributes semanticAttributes = new SemanticAttributes();
    semanticAttributes.put(SemanticAttributes.KEY_CURRENCY, "USD");
    Airbridge.trackEvent(StandardEventCategory.HOME_VIEW, "event_action", "event_label", eventValue, eventAttributes, semanticAttributes);

    If your application has specific needs that are not covered by a standard event category, you can log custom events as below.

    12345
    Number eventValue = 10;
    Map<String, String> eventAttributes = new HashMap<String, String>();
    Map<String, String> semanticAttributes = new HashMap<String, String>();
    semanticAttributes.put(SemanticAttributes.KEY_CURRENCY, "USD");
    Airbridge.trackEvent("event_category", "event_action", "event_label", eventValue, eventAttributes, semanticAttributes);

    Please refer to guide for more details on semantic attributes supported by the Airbridge SDK.

    Alternatively, you can pre-define classes and inherit them depending on the event your app needs.

    12345678
    class MyAppEvent extends Event {
        public MyAppEvent() {
            super("my_custom_category");
        }
    }
    ...
    Airbridge.trackEvent(new MyAppEvent());
    ...

    Sending Standard Events

    User Sign up

    123456
    Airbridge.getCurrentUser().setEmail("me@sample.com");
    Airbridge.getCurrentUser().setPhone("821012341234");
    Airbridge.getCurrentUser().setId("12345");
    Airbridge.getCurrentUser().setAlias("alias1", "value");
    Airbridge.getCurrentUser().setAttributes("attr1", 1234);
    Airbridge.trackEvent(StandardEventCategory.SIGN_UP);

    User Sign in

    123456
    Airbridge.getCurrentUser().setEmail("me@sample.com");
    Airbridge.getCurrentUser().setPhone("821012341234");
    Airbridge.getCurrentUser().setId("12345");
    Airbridge.getCurrentUser().setAlias("alias1", "value");
    Airbridge.getCurrentUser().setAttributes("attr1", 1234);
    Airbridge.trackEvent(StandardEventCategory.SIGN_IN);

    User Sign out

    12
    Airbridge.trackEvent(StandardEventCategory.SIGN_OUT);
    Airbridge.expireUser();

    View Home Screen

    1
    Airbridge.trackEvent(StandardEventCategory.HOME_VIEW);

    View Search Results

    123
    SemanticAttributes semanticAttributes = new SemanticAttributes();
    semanticAttributes.setQuery("Coca Cola");
    Airbridge.trackEvent(StandardEventCategory.SEARCH_RESULT_VIEW, null, null, null, null, semanticAttributes);

    View Product List

    1234567891011121314151617181920
    Product fanta = new Product();
    fanta.setId("fanta_orange");
    fanta.setName("FANTA Orange");
    fanta.setQuantity(1);
    fanta.setCurrency("usd");
    fanta.setPrice(1.99);
    fanta.setPosition(0);
    
    Product cocacola = new Product();
    cocacola.setId("cocacola_low_sugar");
    cocacola.setName("Cocacola Low Sugar");
    cocacola.setQuantity(1);
    cocacola.setCurrency("usd");
    cocacola.setPrice(2.99);
    cocacola.setPosition(1);
    
    SemanticAttributes semanticAttributes = new SemanticAttributes();
    semanticAttributes.setProductListId("beverage_1");
    semanticAttributes.setProducts(Arrays.asList(fanta, cocacola));
    Airbridge.trackEvent(StandardEventCategory.PRODUCT_LIST_VIEW, null, null, null, null, semanticAttributes);

    View Product Details

    12345678910111213141516171819
    Product fanta = new Product();
    fanta.setId("fanta_orange");
    fanta.setName("FANTA Orange");
    fanta.setQuantity(1);
    fanta.setCurrency("usd");
    fanta.setPrice(1.99);
    fanta.setPosition(0);
    
    Product cocacola = new Product();
    cocacola.setId("cocacola_low_sugar");
    cocacola.setName("Cocacola Low Sugar");
    cocacola.setQuantity(1);
    cocacola.setCurrency("usd");
    cocacola.setPrice(2.99);
    cocacola.setPosition(1);
    
    SemanticAttributes semanticAttributes = new SemanticAttributes();
    semanticAttributes.setProducts(Arrays.asList(fanta, cocacola));
    Airbridge.trackEvent(StandardEventCategory.PRODUCT_DETAILS_VIEW, null, null, null, null, semanticAttributes);

    Add to Cart

    12345678910111213141516171819202122232425
    Product fanta = new Product();
    fanta.setId("fanta_orange");
    fanta.setName("FANTA Orange");
    fanta.setQuantity(1);
    fanta.setCurrency("usd");
    fanta.setPrice(1.99);
    fanta.setPosition(0);
    
    Product cocacola = new Product();
    cocacola.setId("cocacola_low_sugar");
    cocacola.setName("Cocacola Low Sugar");
    cocacola.setQuantity(1);
    cocacola.setCurrency("usd");
    cocacola.setPrice(2.99);
    cocacola.setPosition(1);
    
    SemanticAttributes semanticAttributes = new SemanticAttributes();
    semanticAttributes.setCartId("cart_123");
    semanticAttributes.setProducts(Arrays.asList(fanta, cocacola));
    semanticAttributes.setCurrency("usd");
    
    Event event = new Event(StandardEventCategory.ADD_TO_CART);
    event.setValue(4.98);
    event.setSemanticAttributes(semanticAttributes);
    Airbridge.trackEvent(event);

    Order Complete

    12345678910111213141516171819202122232425
    Product fanta = new Product();
    fanta.setId("fanta_orange");
    fanta.setName("FANTA Orange");
    fanta.setQuantity(1);
    fanta.setCurrency("usd");
    fanta.setPrice(1.99);
    fanta.setPosition(0);
    
    Product cocacola = new Product();
    cocacola.setId("cocacola_low_sugar");
    cocacola.setName("Cocacola Low Sugar");
    cocacola.setQuantity(1);
    cocacola.setCurrency("usd");
    cocacola.setPrice(2.99);
    cocacola.setPosition(1);
    
    SemanticAttributes semanticAttributes = new SemanticAttributes();
    semanticAttributes.setProducts(Arrays.asList(fanta, cocacola));
    semanticAttributes.setCurrency("usd");
    semanticAttributes.setInAppPurchased(true);
    
    Event event = new Event(StandardEventCategory.ORDER_COMPLETED);
    event.setValue(4.98);
    event.setSemanticAttributes(semanticAttributes);
    Airbridge.trackEvent(event);

    Verify Event Transmission

    Event information sent from the Airbridge SDK should be seen in the "Airbridge dashboard → Raw Data → App Real-time Log" tab.

    Advanced Setup


    Install Restricted SDK

    Restricted SDK does not collect device IDs, including Ad ID. The restricted SDK will be available starting from v2.22.2.

    Install using Gradle

    Add the following line within the dependencies block in the app/build.gradle file instead of the existing library.

    12345
    dependencies {
        ...
        implementation "io.airbridge:sdk-android-restricted:2.+"
        ...
    }

    Install without Gradle

    Library

    Link

    Airbridge SDK restricted

    Download

    SDK Signature Setup

    Protection against SDK spoofing is available once you set up the app's SDK signature. Settings can be changed by calling setSDKSignatureSecret before the SDK initialization code.

    1234
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
            .setSDKSignatureSecret("YOUR_SDK_SIGNATURE_SECRET_ID", "YOUR_SDK_SIGNATURE_SECRET")
            .build();
    Airbridge.init(this, config);

    Please ask your CSM for the "SDK Signature Secret ID" and "SDK Signature Secret" values.

    User Identifier Hash Setup

    If you want to send user identity information without hashing it for internal data analysis, you can disable hashing by turning off the following option.

    Attention

    Other security measures must be taken internally when sensitive personal information such as "User Email" and "User Phone" is being handled.

    12345
    // Default User Info Hash Enabled = true
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setUserInfoHashEnabled(false)
        .build();
    Airbridge.init(this, config);

    Session Timeout Settings

    Airbridge SDK does not resend an app open event if the user relaunches the app within the set session time. It will only send an app open event when the user opens the app after the set session time.

    12345
    // Default Session Timeout = 5 minutes
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setSessionTimeoutSeconds(300)
        .build();
    Airbridge.init(this, config);

    Privacy Protection

    Use this function if privacy laws apply, and data should only be collected and transferred with consent. (e.g GDPRCCPA)

    123456789101112
    // Default Auto Start Tracking Enabled = true
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setAutoStartTrackingEnabled(false)
        .build();
    Airbridge.init(this, config);
    
    ...
    
    // Set a variable like below
    if (properties.isGDPRAccepted) {
        Airbridge.startTracking();
    }

    It may be difficult to see the re-engagement performance through Airbridge if there are too many deep link actions within the advertiser's app. The following option can be used to receive deep link events for Airbridge deep links only.

    This option will measure deep links only if the following requirements are met.

    • The app is opened through a airbridge.iolink

    • The app is opened through a deeplink.pagelink

    • The app is opened through a Custom Domain Setup that is registered on the Airbridge dashboard

    • The app is opened through a link that contains airbridge_referrerinformation in the query

    12345
    // Default Airbridge Link Only = false
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setTrackAirbridgeLinkOnly(true)
        .build();
    Airbridge.init(this, config);

    The settings below will allow Airbridge SDK to utilize Facebook's deferred app link information.

    Reference - https://developers.facebook.com/docs/app-events/getting-started-app-events-android Reference - https://developers.facebook.com/docs/app-ads/deep-linking

    Add the following repository to the project/build.gradle file.

    123456789
    allprojects {
        ...
        repositories {
            ...
            mavenCentral()
            ...
        }
        ...
    }

    Add the following under the dependencies block of the app/build.gradle file.

    12345
    dependencies {
        ...
        implementation 'com.facebook.android:facebook-android-sdk:latest.release'
        ...
    }

    Add the following string in the app/res/values/string.xml file.

    12345
    ...
    <string name="facebook_app_id">FACEBOOK_APP_ID</string>
    <string name="facebook_client_token">FACEBOOK_CLIENT_TOKEN</string>
    ...
    

    Add the following meta-data under the application element in the AndroidManifest.xml file.

    12345678
    ...
    <application android:label="@string/app_name" ...> 
        ...
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
        <meta-data android:name="com.facebook.sdk.ClientToken" android:value="@string/facebook_client_token"/>
        ...
    </application>
    ...

    Set the below option to true.

    12345
    // Default Facebook Deferred App Link Enabled = false
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setFacebookDeferredAppLinkEnabled(true)
        .build();
    Airbridge.init(this, config);

    App Uninstallation Tracking

    App uninstallation tracking through Firebase Messaging is supported by Airbridge Android SDK v2.6.0 and above.

    Please refer to this page for more information on app uninstallation tracking.

    User Location Information Collection

    Airbridge SDK can collect user location information through the following method.

    Attention

    Location information must be collected for legal purposes through legal methods.

    1234
    // Choose one
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    ...
    12345
    // Default Location Collection Enabled = false
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setLocationCollectionEnabled(true)
        .build();
    Airbridge.init(this, config);

    Attention

    Airbridge SDK collects LastKnownLocation information. If the GPS information is not obtained, the value may not exist even if the corresponding permissions and settings are complete.

    Inflow Measurement Per App Market

    If advertisers need to analyze their application inflow performance for each market separately(e.g. Google Play Store, One Store, Huawei Store), you can set identifiers for each application and it will be reflected on the Airbridge dashboard.

    Setup via AndroidManifest.xml

    Insert the app market's name(e.g. playStoreoneStorehuaweiStore) at andriod:value.

    1234567
    ...
    <application android:label="@string/app_name" ...> 
        ...
        <meta-data android:name="co.ab180.airbridge.app_market_identifier" android:value="playStore"/>
        ...
    </application>
    ...

    Setup via AirbridgeConfig

    Insert the app market's name(e.g. playStoreoneStorehuaweiStore) at setAppMarketIdentifier.

    1234
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setAppMarketIdentifier("playStore")
        .build();
    Airbridge.init(this, config);

    The data can be utilized at the Airbridge dashboard through "Reports → Actuals → GroupBy → Event Property → App Market Identifier" and "Raw Data → App Raw Data → Export Raw Data → Select Property → App Market Identifier".

    Installations per App Market

    Error Log Collection

    Error logs of the SDK are sent to the Airbridge server to improve the quality of the Airbridge SDK. These error logs only include the SDK's internal operations. You can disable this by turning off the following option.

    12345
    // Default Error Log Collection Enabled = true
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setErrorLogCollectionEnabled(false)
        .build();
    Airbridge.init(this, config);

    Event Buffer Limit

    When an event transmission failure occurs, the Airbridge SDK will store the event and retry at a later time. The following settings will allow you to limit the storage used for such events.

    1234567
    int count = 10;
    long bytes = 1000000L;
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setEventMaximumBufferCount(count)
        .setEventMaximumBufferSize(bytes)
        .build();
    Airbridge.init(this, config);

    Event buffer size is slightly smaller than the actual size of the data due to metadata management.

    Meta install referrer Collection Setup

    Meta install referrer (MIR) Colection Setup supported by Airbridge Android SDK in version 2.22.3 or higher. To collect data, set as below.

    After adding the settings, you must enter the decryption key to see decrypted MIR. Refer to this article to learn about MIR.

    1234
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setMetaInstallReferrer("YOUR_FACEBOOK_APP_ID")
        .build();
    Airbridge.init(this, config);

    DMA Compliance Setup

    To comply with the Digital Markets Act (DMA), user consent must be shared with Airbridge. For detailed information about the DMA and the guidelines for advertisers, refer to this article.

    Note that consent from all end users in the European Economic Area (EEA) should always be shared with Airbridge.

    1. Confirm whether the end user launched the app in the EEA. If the end user did launch the app in the EEA (eea=1) and DMA applies, confirm whether the consent values are already stored for the session. If there are consent values stored, continue to Step 3.

    If the end user launched the app from outside the EEA, it is not necessary to collect user consent.

    Note

    Airbridge cannot provide guidance on storing the consent values or the development and implementation of privacy prompts. For assistance, consult legal professionals.

    2. If there are no consent values stored, proceed to obtain user consent, such as with a privacy prompt. You must collect the adPersonalization and adUserData values in this step.

    3. Initialize the Airbridge SDK and share the consent values with Airbridge before collecting the end user’s personal data.

    Attention

    • Use the field names specified by Airbridge: eea, adPersonalization, and adUserData.

    • Fill in 0 or 1 in accordance with the consent values collected.

    1234567891011121314151617181920
    // MainApplication.kt
    override fun onCreate() {
        super.onCreate()
        // Initialize Airbridge SDK
        val config = AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
            // Make Airbridge SDK explicitly start tracking
            .setAutoStartTrackingEnabled(false)
            .build()
        Airbridge.init(this, config)
    
        // Set device alias into Airbridge SDK
        // Based on actual region
        Airbridge.setDeviceAlias("eea", "0" or "1")
    
        // Based on actual user consent
        Airbridge.setDeviceAlias("adPersonalization", "0" or "1")
        Airbridge.setDeviceAlias("adUserData", "0" or "1")
        
        // Explicitly start tracking
        Airbridge.startTracking()

    Attribution Result Callback Setup

    Get attribution result data using the Airbridge SDK.

    123456789
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
    	.setOnAttributionResultReceiveListener(new OnAttributionResultReceiveListener() {
    		@Override
    		public void onAttributionResultReceived(@NonNull Map<String, String> result) {
    			// Process attribution data
    		}
    	})
    	.build();
    Airbridge.init(this, config);
    • Below is a list of data fields that will be retrieved through the callback.

    Field

    Description

    attributedChannel

    Channel (String)

    attributedCampaign

    Campaign (String)

    attributedAdGroup

    Ad Group (String)

    attributedAdCreative

    Ad Creative (String)

    attributedContent

    Content (String)

    attributedTerm

    Keyword (String)

    attributedSubPublisher

    Sub Publisher (String)

    attributedSubSubPublisher1

    Sub-sub Publisher 1 (String)

    attributedSubSubPublisher2

    Sub-sub Publisher 2 (String)

    attributedSubSubPublisher3

    Sub-sub Publisher 3 (String)

    • If the event is unattributed, below is an example of the response you'll get.

    123
    {
        "attributedChannel": "unattributed"
    }

    Guidelines for using attribution result data

    • Attribution data exists

    1. Attribution data is forwarded within 40 seconds of SDK initialization.

    2. If the app was closed and attribution data wasn't received, attribution data is forwarded within 40 seconds when the app is opened again.

    3. On very rare occasions, attribution data could take up to 5 minutes to be received.

    • Attribution data does not exist

    1. Attribution data will be received 3 hours after SDK initialization.

    It is not recommended to utilize these attribution values for real-time processing

    Event Transmission Interval

    It is possible to setup event transmission intervals using the below code.

    12345
    // Default Event Transmit Interval = 0 millisecond
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setEventTransmitInterval(3000)
        .build();
    Airbridge.init(this, config);

    Attention

    An IllegalArgumentExcpeionruntime error will occur if setEventTransmitIntervalis set to a negative number.

    Lifecycle Event Collection Within Session

    The following code allows you to collect lifecycle events (ORGANIC_REOPENFOREGROUND) within the session timeframe.

    1234
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setTrackInSessionLifeCycleEventEnabled(true)
        .build();
    Airbridge.init(this, config);

    Delete Unprocessed Events

    Empty the device's internal DB of unprocessed events that were not sent to Airbridge.

    1234
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setResetEventBufferEnabled(true)
        .build();
    Airbridge.init(this, config);

    Redirect users to other pages without going through a browser by using the below feature.

    12
    Airbridge.click("https://abr.ge/~~~")
    Airbridge.impression("https://abr.ge/~~~")

    Attention

    Custom domain tracking links with custom short IDs can't be used.

    Deactivate Airbridge

    All Airbridge functions can be turned off.

    1234
    AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        .setSdkEnabled(false)
        .build();
    Airbridge.init(this, config);

    Attention

    If setResetEventBufferEnabled is set to true and setSdkEnabled is set to false, then setSdkEnabled is prioritized and setResetEventBufferEnabled isn't processed.

    Hybrid App Setup


    While basic events (e.g. "install", "open", "deep link open") can be automatically tracked by only installing the Android SDK in your hybrid app, in-app events (e.g. sign-up, purchase, etc.) cannot be tracked as they are actually in-browser events that occur within a website of the WebView environment. Airbridge provides a simpler way to track in-app events by enabling the Android SDK to automatically pull all events from the web SDK that is installed on the website of the WebView environment. This replaces the hassle of having to create bridge functions between native and WebView environments.

    Attention

    Please note that in order to utilize this feature, both SDKs must be installed; Android SDK on the mobile native environment and web SDK on the website of the WebView environment.

    Sending Events in WebView Environments

    Reference - Building Web Apps in WebView

    Reference - Understanding Android WebView Javascript Interface

    Please call the Airbridge::setJavascriptInterface method in the target WebView as below.

    123456789101112131415161718192021
    public class MainActivity extends Activity {
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initWebView();
        }
        
        void initWebView() {
            webView = findViewById(R.id.webView);
            webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setDomStorageEnabled(true);
    
            Airbridge.setJavascriptInterface(webView, "YOUR_WEB_SDK_TOKEN");    
        
            webView.setWebChromeClient(new WebChromeClient());
            webView.setWebViewClient(new WebViewClient());
            webView.loadUrl("http://dev.blog.airbridge.io/websdk-web-app/");
        }
    }

    You can find YOUR_WEB_TOKEN in the "Airbridge dashboard → Settings → Tokens" tab

    Setup the SDK on the actual web page by following the Web SDK guide

    123456
    (function(a_,i_,r_,_b,_r,_i,_d,_g,_e){if(!a_[_b]||!a_[_b].queue){_g=i_.getElementsByTagName(r_)[0];a_[_b]={queue:[]};_d={};for(_i=0;_i<_r.length;_d={$jscomp$loop$prop$m$2:_d.$jscomp$loop$prop$m$2},_i++)_d.$jscomp$loop$prop$m$2=_r[_i],~_d.$jscomp$loop$prop$m$2.indexOf(".")&&(_e=_d.$jscomp$loop$prop$m$2.split(".")[0],a_[_b][_e]=a_[_b][_e]||{},a_[_b][_e][_d.$jscomp$loop$prop$m$2.split(".")[1]]=function(_d){return function(){a_[_b].queue.push([_d.$jscomp$loop$prop$m$2,arguments])}}(_d)),a_[_b][_d.$jscomp$loop$prop$m$2]=function(_d){return function(){a_[_b].queue.push([_d.$jscomp$loop$prop$m$2,arguments])}}(_d);_d=i_.createElement(r_);_d.async=1;_d.src="//static.airbridge.io/sdk/latest/airbridge.min.js";_g.parentNode.insertBefore(_d,_g)}})(window,document,"script","airbridge","init setBanner setDownload setDeeplinks sendSMS sendWeb setUserAgent setUserAlias addUserAlias setMobileAppData setUserId setUserEmail setUserPhone setUserAttributes setDeviceIFV setDeviceIFA setDeviceGAID events.send events.signIn events.signUp events.signOut events.purchased events.addedToCart events.productDetailsViewEvent events.homeViewEvent events.productListViewEvent events.searchResultViewEvent".split(" "));
    
    airbridge.init({
        app: 'YOUR_APP_NAME',
        webToken: 'YOUR_WEB_SDK_TOKEN'
    });

    Troubleshooting


    Dependencies

    java.lang.NoClassDefFoundError: kotlin/coroutines/AbstractCoroutineContextKey Error

    12345678910111213141516171819202122232425262728
    <activity ...>  
        ...  
        <intent-filter android:autoVerify="true">  
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="http" android:host="YOUR_APP_NAME.deeplink.page" />
            <data android:scheme="https" android:host="YOUR_APP_NAME.deeplink.page" />
        </intent-filter>
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="http" android:host="YOUR_APP_NAME.airbridge.io" />
            <data android:scheme="https" android:host="YOUR_APP_NAME.airbridge.io" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="YOUR_APP_URI_SCHEME" />
        </intent-filter>
    </activity>

    Reference - https://github.com/Kotlin/kotlinx.coroutines/issues/1879

    According to @qwwdfsad, the use of "kotlin-stdlib 1.3.70" and above is enforced when using "kotlinx-coroutines-core 1.3.5" and above.

    Make sure that you're using "kotlin-stdlib 1.3.70" and above if you're using "kotlinx-coroutines-core 1.3.5" and above through the gradlew dependencies command.

    Auto Backup

    Reference - https://developer.android.com/guide/topics/data/autobackup

    Airbridge SDK defines airbridge_auto_backup_rules.xml in AndroidManifest.xml to prevent automatic replication of internal data. If you need Auto Backup for your Android app, you have to merge with airbridge_auto_backup_rules.xml file yourself

    When errors like Manifest merger failed : Attribute application@fullBackupContent value=(true) occur, please add the following rules in your backup_rules.xml file and add tools:replace="android:fullBackupContent" inside application element

    Airbridge SDK defines airbridge_auto_backup_rules.xml in AndroidManifest.xml to prevent automatic replication of internal data. You may have to configure your auto backup rules if your app uses auto backup, which in turn might cause conflicts such as Manifest merger failed : Attribute application@fullBackupContent value=(true).

    If such errors occur, you will need to set tools:replace="android:fullBackupContent" under the application element and merge the following rules to your backup_rules.xml file.

    Below are the auto backup rules defined in the Airbridge SDK.

    123456789
    <?xml version="1.0" encoding="utf-8"?>
    <full-backup-content>
        <exclude domain="sharedpref" path="airbridge-internal" />
        <exclude domain="sharedpref" path="airbridge-install" />
        <exclude domain="sharedpref" path="airbridge-user-info" />
        <exclude domain="sharedpref" path="airbridge-user-alias" />
        <exclude domain="sharedpref" path="airbridge-user-attributes" />
        <exclude domain="database" path="airbridge.db" />
    </full-backup-content>

    Was this page helpful?

    Have any questions or suggestions?