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
}
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:
| Parameter | Required | Description |
|---|---|---|
clientId | Yes | Client ID provided by the Hubble team |
appSecret | Yes | App secret provided by the Hubble team |
token | Conditional | SSO token for the current user. Required unless lazy login is enabled. |
appVersion | No | App version string. Defaults to "10000". |
deviceId | No | Device 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)
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()
}
}
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
| Action | When It Fires | What You Should Do |
|---|---|---|
app_ready | SDK has finished loading | Show the WebView / iframe. Hide your loading spinner. |
close | User tapped the close or back button in the SDK | Dismiss the WebView / iframe. Navigate the user back. |
error | SDK failed to load (invalid credentials, network error, SSO failure) | Hide the WebView. Show a user-friendly error with a retry option. |
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.
If UPI apps are not appearing, verify:
- The
<queries>block is present inAndroidManifest.xml - Your WebView is configured to handle external intents in
shouldOverrideUrlLoading() - You are testing on a physical device (not an emulator)
Best Practices
- Destroy the WebView: Call
webView.destroy()in your Fragment'sonDestroyViewor Activity'sonDestroy. WebViews consume significant memory. - Show a loading state: Keep the WebView hidden until you receive the
app_readycallback. Show a native loading spinner. - Handle errors: Show a native error screen with a retry option when the
errorcallback fires. - Test on real devices: WebView behavior differs between emulators and physical devices, especially for UPI payments.
Legacy: Android SDK (Deprecated)
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.