Skip to main content

Android Integration Guide

This guide covers how to integrate the Hubble SDK into an Android application using a WebView. The SDK is a web application that runs inside your WebView.

1. Setup the WebView

Create a WebView and configure the required settings. All of these settings are necessary for the SDK to function correctly:

webView.apply {
settings.javaScriptEnabled = true
settings.javaScriptCanOpenWindowsAutomatically = true
settings.databaseEnabled = true
settings.domStorageEnabled = true
settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
settings.setSupportZoom(false)
settings.builtInZoomControls = false
settings.displayZoomControls = false
}
Missing Settings = Broken SDK

Unlike modern browsers, Android WebView has most advanced features disabled by default. If you skip domStorageEnabled or javaScriptEnabled, the SDK will show a blank screen or fail to complete payments. Always enable all settings listed above.

2. Initialization

Build the SDK URL with your credentials and the platform parameter:

ParameterRequiredDescription
clientIdYesClient ID provided by the Hubble team
appSecretYesApp secret provided by the Hubble team
tokenConditionalSSO token for the current user. Required unless lazy login is enabled.
appVersionNoApp version string. Defaults to "10000".
deviceIdNoDevice identifier for analytics.
val clientId = "your_client_id"
val appSecret = "your_app_secret"
val token = "your_user_token"
val appVersion = BuildConfig.VERSION_NAME
val deviceId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)

// Use "sdk.dev.myhubble.money" for development
val baseUrl = "sdk.myhubble.money"

val sdkUrl = "https://$baseUrl/?clientId=$clientId&appSecret=$appSecret&token=$token&appVersion=$appVersion&deviceId=$deviceId&wrap-plt=an"

3. Load the WebView

webView.addJavascriptInterface(HubbleJavaScriptInterface(this), "AndroidHost")
webView.webViewClient = HubbleWebViewClient()
webView.loadUrl(sdkUrl)
Fresh WebView Every Time

Create a new WebView each time the user opens the gift card store. Do not cache or reuse WebViews. This ensures a fresh SSO token and current data.

4. Handling Navigation

Implement shouldOverrideUrlLoading() to keep Hubble and payment gateway URLs inside the WebView, while opening all other URLs in the device’s default browser:

class HubbleWebViewClient : WebViewClient() {
private val baseUrl = "sdk.myhubble.money" // For dev: "sdk.dev.myhubble.money"

override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
val url = request?.url?.toString() ?: return false

return if (url.contains(baseUrl)) {
false // Load within WebView
} else {
// Open external URLs (UPI, browser links, etc.)
try {
val intent = Intent(Intent.ACTION_VIEW, request?.url)
view?.context?.startActivity(intent)
true
} catch (e: Exception) {
false
}
}
}
}

Back Navigation

Override onBackPressed() in your Activity to handle in-WebView navigation:

override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else {
super.onBackPressed()
}
}
Handle createWebViewWith

Some payment gateways open links in a new window. Override createWebViewWith in your WebChromeClient to load these URLs in the current WebView instead of letting them fail silently.

5. Handling Events

The SDK communicates with your app through two types of events: action events and analytics events.

Action Events

ActionWhen It FiresWhat You Should Do
app_readySDK has finished loadingShow the WebView / iframe. Hide your loading spinner.
closeUser tapped the close or back button in the SDKDismiss the WebView / iframe. Navigate the user back.
errorSDK failed to load (invalid credentials, network error, SSO failure)Hide the WebView. Show a user-friendly error with a retry option.
Always Handle the close Event

The close action is the only way the SDK tells your application that the user wants to leave. If you do not handle it, the user will be stuck inside the SDK with no way to navigate back. This is one of the most common integration issues.

Analytics Events

Analytics events are sent as JSON and can be forwarded to your analytics providers:

{ "type": "analytics", "event": "payment_success", "properties": { "amount": 500 } }

Forward analytics events to your analytics provider (Mixpanel, CleverTap, Amplitude, etc.) to track SDK usage.

For a complete list of events, see the Full Events Reference.

Setting Up the Event Bridge

Register a JavaScript interface with the name "AndroidHost". The SDK calls methods on this object:

class HubbleJavaScriptInterface {
@JavascriptInterface
fun close() {
// User tapped close - dismiss the WebView
activity?.finish()
}

@JavascriptInterface
fun reload() {
// Reload the WebView
webView.reload()
}

@JavascriptInterface
fun onAnalyticsEvent(eventName: String, properties: String?) {
val propertiesMap = properties?.let {
try {
val json = JSONObject(it)
val map = mutableMapOf<String, Any>()
json.keys().forEach { key -> map[key] = json[key] }
map
} catch (e: JSONException) { emptyMap() }
}
// Forward to your analytics provider
Log.d("HubbleSDK", "Event: $eventName, Props: $propertiesMap")
}
}

webView.addJavascriptInterface(HubbleJavaScriptInterface(), "AndroidHost")

6. Payment Configuration

The Hubble SDK supports UPI and credit/debit card payments. Credit/debit card payments are not enabled by default - contact Hubble support to enable them.

UPI on Android

On Android 11 (API level 30) and above, apps must declare which packages they can query. Add the following to your AndroidManifest.xml:

<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="upi" />
</intent>
</queries>

This allows the WebView to post the UPI intent to the system, which then transfers control to the appropriate UPI app.

UPI Apps Not Appearing

If UPI apps are not appearing, verify:

  1. The <queries> block is present in AndroidManifest.xml
  2. Your WebView is configured to handle external intents in shouldOverrideUrlLoading()
  3. You are testing on a physical device (not an emulator)

Best Practices

  • Destroy the WebView: Call webView.destroy() in your Fragment's onDestroyView or Activity's onDestroy. WebViews consume significant memory.
  • Show a loading state: Keep the WebView hidden until you receive the app_ready callback. Show a native loading spinner.
  • Handle errors: Show a native error screen with a retry option when the error callback fires.
  • Test on real devices: WebView behavior differs between emulators and physical devices, especially for UPI payments.

Legacy: Android SDK (Deprecated)

warning

The Hubble Android SDK is deprecated and no longer recommended for new integrations. Please use the WebView integration documented above. Existing integrations using the SDK will continue to work, but we recommend migrating to the WebView approach for better control and maintainability.

The Android SDK was a lightweight Android library around our web application. If you're currently using it, here's the reference documentation:

Setup

  • Add Jitpack repository to your project's Gradle file:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
  • Add the dependency:
dependencies {
implementation ("money.myhubble:storesdk:0.0.3")
}
  • Initialize the SDK:
Hubble.init(
env="dev", // If not given, will default to 'prod'
token="GOpBKIQ0xj", // Some token or ID that uniquely identifies your user
clientId= "clientA", // will be provided by Hubble team
appSecret= "appSecretA", // will be provided by Hubble team
)
  • Open the store:
Hubble.open(context = context)

SDK Features

Fragments:

hubbleFragment = Hubble.getFragment()
hubbleFragment.goBack() // returns true/false

Events:

Hubble.init(
...
onAnalyticsEvent = { eventName: String, props: Map<String, Any> ->
Log.i(tag, "Received event $eventName from Hubble SDK. ${props}")
}
)

Deeplinks:

Hubble.init(
...
page = HubblePage(
page = "brand",
params = mapOf("brandId" to "uber")
)
)

For migration assistance, please contact the Hubble team.