English | 한국어
Clone this repo and run the sample app to see how the Airbridge Android SDK works.
Follow each step below to walk through SDK initialization, deeplinks, event tracking, and hybrid WebView event tracking.
For each step's expected logs, filter Android Studio Logcat by the
Airbridgetag.
-
Clone this repo
-
Open the
android/folder in Android Studio -
In
AndroidApplication.kt, replace the 3 constants with your values (Airbridge Dashboard > Settings > Tokens)companion object { // Replace these with your own values from the Airbridge dashboard // (Settings > Tokens). const val APP_NAME = "YOUR_APP_NAME" const val APP_TOKEN = "YOUR_APP_SDK_TOKEN" const val WEB_TOKEN = "YOUR_WEB_SDK_TOKEN" val WEB_URL: String get() = "https://ab180.github.io/airbridge-example/?app_name=$APP_NAME&web_sdk_token=$WEB_TOKEN" }
Replace this Dashboard field YOUR_APP_NAMEApp name YOUR_APP_SDK_TOKENApp SDK token YOUR_WEB_SDK_TOKENWeb SDK token -
Wait for Gradle Sync to run automatically
- If the 'Sync Now' banner appears at the top, click it. If not, it's already synced.
-
Run on an emulator or real device
AndroidApplication.kt's onCreate() initializes the SDK.
// ===== Airbridge SDK: Initialize =====
val option = AirbridgeOptionBuilder(APP_NAME, APP_TOKEN)
// Debug logs: development only. Remove before release.
.setLogLevel(AirbridgeLogLevel.DEBUG)
.build()
Airbridge.initializeSDK(this, option)APP_NAME and APP_TOKEN are the constants defined at the top of AndroidApplication.kt — they reference the values you replaced in Step 1.
⚠️ .setLogLevel(AirbridgeLogLevel.DEBUG)is for development only. Remove it before releasing.
Expected logs
Airbridge I {initializeSDK} is called
Airbridge I Airbridge is initialized
Airbridge I startTracking signal is sent automatically
Airbridge I Track lifecycle event: eventType={ORGANIC_OPEN}
Airbridge I Successfully fetched the DeviceUUID
Airbridge I Succeed to send event packets to Airbridge
Airbridge is initialized confirms SDK init succeeded.
The
Failed to fetch attributionline that appears alongside is the normal response for organic installs with no attribution info. It's not an error.
Deeplinks take users directly to a specific screen when they tap a link.
When a tracking link is opened, Airbridge picks the best option for the user's environment between App Link and scheme deeplink to open the app.
After the app opens, the SDK converts it to the scheme deeplink form configured in the tracking link (e.g. exabr://detail) and hands it to the app.
exabris just an example URI Scheme. Real apps use their own URI Scheme.
flowchart LR
TL[Tracking Link<br/>tap] -- "Scheme Deeplink<br/>or<br/>App Link<br/>(Deeplink)" --> SDK
TL -- "Redirect<br/>(Not Installed)" --> Store[Store<br/>or<br/>Website]
Store --> Install["Install<br/>&<br/>Open"]
Install -- "Scheme Deeplink<br/>or<br/>App Link<br/>(Deferred Deeplink)" --> SDK
subgraph App
SDK[SDK] --> Out[Scheme Deeplink]
end
Delivery flow
| Scenario | Flow |
|---|---|
| App installed | Tracking link → App opens via App Link or scheme deeplink → SDK converts and delivers scheme deeplink |
| App not installed (deferred deeplink) | Tracking link → Store → First launch after install → SDK delivers the stored scheme deeplink |
See the Android SDK deeplink setup guide for details on deeplink and deferred deeplink setup.
Airbridge deeplink forms
| Form | Example |
|---|---|
| Scheme deeplink | YOUR_SCHEME://product/12345?airbridge_referrer=... |
| App Link | https://YOUR_APP_NAME.airbridge.io/...or https://YOUR_APP_NAME.abr.ge/... |
-
This sample app is designed to be verified with scheme deeplinks alone.
-
In production, the app may open via either App Link or scheme deeplink depending on the environment, so you'll want to set up App Links too.
-
The
intent-filterfor App Links is already included inAndroidManifest.xml— just register your app name and SHA256 certificate fingerprint.See the App Links Setup appendix for the full procedure.
- Receive — The
intent-filterinDeeplinkActivity.ktis configured to receive scheme deeplinks and App Links. - Convert —
DeeplinkActivity.ktcallsAirbridge.handleDeeplinkto convert to the scheme deeplink and pass it to the callback. If it's not an Airbridge deeplink, the callback isn't invoked andfalseis returned. - Route — The converted scheme deeplink arrives in the callback. Read its
urito navigate to the desired screen.
// ===== Airbridge SDK: Deeplink =====
val isAirbridgeDeeplink = Airbridge.handleDeeplink(intent) { uri ->
if (uri != null) {
val target = when (uri.host) {
"main" -> MainActivity::class.java
"detail" -> DetailActivity::class.java
"webview" -> WebViewActivity::class.java
else -> MainActivity::class.java
}
startActivity(Intent(this, target).apply { data = uri })
}
}
if (isAirbridgeDeeplink) returnDeferred deeplinks come back via
Airbridge.handleDeferredDeeplinkon first launch after install, called inMainActivity.kt. The stored scheme deeplink (if any) is passed to the callback; otherwiseuriisnull.Routing isn't handled by the SDK, so you implement it the same way as for regular deeplinks.
// ===== Airbridge SDK: Deferred Deeplink =====
Airbridge.handleDeferredDeeplink { uri ->
if (uri != null) {
val target = when (uri.host) {
"detail" -> DetailActivity::class.java
"webview" -> WebViewActivity::class.java
else -> null
}
if (target != null) {
startActivity(Intent(this, target).apply { data = uri })
}
}
}flowchart LR
subgraph Normal [Regular deeplink]
direction TB
Click[Tracking link tap] --> Resume["DeeplinkActivity.onResume()"]
Resume --> Handle["Airbridge.handleDeeplink"]
end
subgraph Deferred [Deferred deeplink]
direction TB
Install["First launch<br/>after install"] --> MainCreate["MainActivity.onCreate()"]
MainCreate --> HandleD["Airbridge.handleDeferredDeeplink"]
end
Handle -- "Converted<br/>scheme deeplink" --> Route{"Branch on uri.host"}
HandleD -- "Converted<br/>scheme deeplink" --> Route
Route --> Acts["MainActivity<br/>DetailActivity<br/>WebViewActivity"]
Order: register deeplink info → pick a test path → verify with a tracking link.
-
Go to Airbridge Dashboard > Tracking Link > Deeplink
-
Enter the following in the Android section
Dashboard field Value Sample app example Android URL Scheme YOUR_SCHEME://exabr://Android Package Name com.your.packagenameco.ab180.airbridge.examplesha256_cert_fingerprints SHA256 fingerprint of your keystore Leave blank for scheme-only tests. For App Links see the appendix -
Save
The sample app handles the following paths. When creating a tracking link, enter one of these in Redirect path > Final destination > Deeplink.
| Path | Destination |
|---|---|
exabr://main |
MainActivity |
exabr://detail |
DetailActivity |
exabr://webview |
WebViewActivity |
- Create a tracking link in the Airbridge Dashboard (enter one of the paths above in Redirect path > Final destination > Deeplink)
- Tap the link on a real device
- Verify the app opens and navigates to the configured screen
- Check that the deeplink event was collected in the Dashboard
For more granular environment scenarios (installed/not, scheme/App Link, etc.), use the Airbridge deep linking test console.
Airbridge I {handleDeeplink} is called
Airbridge I Track lifecycle event: eventType={DEEPLINK_OPEN}
Airbridge I Succeed on handling deeplink: url={exabr://detail}
Airbridge D QUEUED - DEEPLINK_OPEN [...]
Airbridge I Succeed to send event packets to Airbridge
Airbridge D FLUSHED - DEEPLINK_OPEN [...]
Succeed on handling deeplink confirms the deeplink was received and converted.
Record user actions such as purchases and cart additions as events. Tap the event buttons in the sample app to see how it works.
An Airbridge event has the following structure.
- Category: The type of event (e.g.
order_completed) - Semantic attributes: Airbridge-defined standard fields (Full list)
- Custom attributes: Additional fields you define freely
// ===== Airbridge SDK: Standard Event =====
Airbridge.trackEvent(
AirbridgeCategory.ORDER_COMPLETED,
mapOf(
AirbridgeAttribute.ACTION to "event_action_example",
AirbridgeAttribute.LABEL to "event_label_example",
AirbridgeAttribute.VALUE to 10000.0,
AirbridgeAttribute.CURRENCY to "KRW",
AirbridgeAttribute.TRANSACTION_ID to "AB-123"
),
mapOf("your_custom_attribute_key" to "your_custom_attribute_value")
)// ===== Airbridge SDK: Custom Event =====
Airbridge.trackEvent("your_custom_event")Custom Events are supported on the Growth Plan.
- Tap the event buttons (
SEND ORDER_COMPLETE,SEND CUSTOM_EVENT) in the sample app - Check that the event was collected in Raw Data > App Event Real-Time Log on the Airbridge Dashboard (Real-Time Log guide)
Expected logs: Standard Event (SEND ORDER_COMPLETE button)
Airbridge I {trackEvent} is called: {airbridge.ecommerce.order.completed} {{action=event_action_example, label=event_label_example, value=10000.0, currency=KRW, transactionID=AB-123}} {{your_custom_attribute_key=your_custom_attribute_value}}
Airbridge I Track in-app event: category={airbridge.ecommerce.order.completed}
Airbridge D QUEUED - UNDEFINED(airbridge.ecommerce.order.completed) [...]
Airbridge V Client request: method={POST} url={https://event.airbridge.io/v1/apps/YOUR_APP_NAME}
Airbridge I Succeed to send event packets to Airbridge
Airbridge D FLUSHED - UNDEFINED [...]
Expected logs: Custom Event (SEND CUSTOM_EVENT button)
Airbridge I {trackEvent} is called: {your_custom_event} {null} {null}
Airbridge I Track in-app event: category={your_custom_event}
Airbridge D QUEUED - UNDEFINED(your_custom_event) [...]
Airbridge V Client request: method={POST} url={https://event.airbridge.io/v1/apps/YOUR_APP_NAME}
Airbridge I Succeed to send event packets to Airbridge
Airbridge D FLUSHED - UNDEFINED [...]
Succeed to send event packets to Airbridge and the FLUSHED line confirm the event was delivered to the Airbridge server.
| Plan | Available events |
|---|---|
| Growth | Standard events + Custom events |
| Core | Standard events only |
| Deeplink | Install, Open, Deeplink Open only |
Forward events, device info, and user info from an in-app WebView to the App SDK. Without this setup, WebView events are counted as web browser traffic.
flowchart LR
U([👤 User])
subgraph APP[📱 App]
direction TB
subgraph WV[🌐 In-app WebView]
ACT["User action<br/>(e.g. purchase / add to cart)"] --> WEB[📦 Web SDK]
end
NAT[📦 App SDK]
WEB -. Bridge .-> NAT
end
U --> ACT
NAT --> SRV[(📈 Airbridge server)]
style APP fill:#fff3b0,stroke:#d4a017,stroke-width:2px
This sample opens a test page with the Airbridge Web SDK pre-installed (ab180.github.io/airbridge-example) in the WebView. The APP_NAME and WEB_TOKEN from Step 1 are appended as URL query parameters, so the test page's Web SDK initializes against your Airbridge app. No separate Web SDK installation is required.
⚠️ PassingAPP_NAME/WEB_TOKENas URL query parameters to init the Web SDK is not the recommended init method. This is an ad-hoc structure for easy build/test of the sample app. In production, follow the Web SDK guide and embed the token directly in your page code.
WebViewActivity.kt wires the App SDK to the Web SDK inside the WebView.
// ===== Airbridge SDK: Hybrid WebView =====
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
Airbridge.setWebInterface(webView, WEB_TOKEN)
webView.webChromeClient = WebChromeClient()
webView.webViewClient = WebViewClient()
webView.loadUrl(WEB_URL)Airbridge.setWebInterfaceconnects the App SDK ↔ Web SDK bridge. It must be called beforewebView.loadUrl(...).- After connecting, events, device info, and user info inside the WebView are routed to Airbridge through the App SDK.
- Tap
OPEN WEBVIEWon the sample app's main screen to move to the WebView - Tap the test buttons (
Send Order Complete,Send Custom Event) inside the WebView to send events - Check that the event was collected in Raw Data > App Event Real-Time Log on the Airbridge Dashboard
Since events are routed through the App SDK, they appear in the App event real-time log, not the Web one.
Expected logs (button tap inside WebView)
Airbridge V Received a message from web interface: method={trackEvent} payload={...}
Airbridge I Succeed to send event packets to Airbridge
Airbridge D FLUSHED - UNDEFINED [...]
Received a message from web interface confirms the WebView event was forwarded to the App SDK, and the FLUSHED line confirms full delivery to the Airbridge server.
See the Hybrid App Setup - Android SDK guide for details.
URI Scheme opens the app with a custom scheme like exabr://detail.
App Links uses HTTPS URLs like https://YOUR_APP_NAME.airbridge.io/... to open the app, with a clean browser fallback when the app isn't installed.
For production, App Links is recommended. You'll need your own Airbridge app and keystore access.
If you already registered the URI Scheme and Package Name in Step 3's Register deeplink info, you only need to register sha256_cert_fingerprints here.
The
intent-filterfor App Links is already included inAndroidManifest.xml. Just replaceYOUR_APP_NAMEwith your Airbridge app name.
Extract the SHA256 fingerprint from your local keystore directly.
keytool -list -v -keystore YOUR_KEYSTORE_PATH -alias YOUR_ALIASOr run the Gradle > signingReport task in Android Studio.
Defaults for testing a debug build:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
In addition to the URI Scheme and Package Name registered in Step 3's Register deeplink info, enter the SHA256 value from above in the sha256_cert_fingerprints field.
- To register multiple fingerprints, separate them with commas (
,) on a single line.- Register dev-mode and production sha256_cert_fingerprints separately.
See the Android SDK > Register deeplink info guide for details.
For common build/event/deeplink issues and fixes, see the Troubleshooting - Android SDK guide.