Android (Native)
Overview
The Appnomix Commerce SDK is a mobile library designed to help brands deepen their relationship with customers by placing the brand prominently on the users' mobile phones.
Version 2.0 introduces significant enhancements including product detection, price comparison features, and a completely overhauled user interface. Version 1.0 focused primarily on coupon functionality.
On Android, the SDK uses the Accessibility Service to track browser interactions, such as the currently rendered page. To enable this service, both the host application and the SDK must coordinate to ensure the user grants the necessary permission.
This requires declaring android.permission.BIND_ACCESSIBILITY_SERVICE in your app manifest, which requires additional Play Console consent requirements handling before submitting the first version of the app with the Appnomix SDK. See the Privacy & Permissions section for detailed guidance.
At this time, the SDK supports interactions only within Google Chrome. Support for additional browsers can be added upon request.
Key Links
- Appnomix Android Sample App
- For any questions regarding the integration, please contact [email protected]
Getting Started
Minimum Requirements
- Android minSDK version 5.0 (API 21)
- Android compileSDK version 15 (API 35)
- Kotlin version 2.0 or higher
Installing the SDK
- Add the SDK dependency inside your current Android Gradle project, linking against the latest version:
repositories {
mavenCentral() // use mavenCentral as the source of this dependency
}android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
// backwards support for newer Java APIs the SDK might be using (e.g. SDK using Java_18, while host app using Java_17)
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
// other project-specific dependencies above/after this
implementation("app.appnomix:sdk:2.0.3")
// backwards support for newer Java APIs the SDK might be using
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
}plugins {
id("org.jetbrains.kotlin.plugin.compose") version "your_kotlin_version"
}plugins {
id("org.jetbrains.kotlin.plugin.compose")
}
android {
buildFeatures {
compose = true
}
}- Inside your app's main Android Application class, setup the Appnomix SDK by providing the needed data, as depicted below.
import android.app.Application
import app.appnomix.sdk.external.AppnomixCSDK
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
AppnomixCSDK.initialize(
authToken = "token_received_from_appnomix",
clientId = "clientId_received_from_appnomix"
)
}
}Starting the SDK
To request Accessibility Service access from the user, the application must launch the Onboarding flow, as depicted below, which explains the SDK’s features and the reasons why this permission is required.
import app.appnomix.sdk.external.AppnomixCSDK
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// you can check for unmet requirements, before launching the onboarding, by requesting them from the SDK and checking if the returned list is empty.
// val unmetRequirements = AppnomixCSDK.unmetRequirements()
if (AppnomixCSDK.isAccessibilityServiceEnabled) {
// the permission is already granted, you can proceed with the rest of your app logic
return
}
// Checks whether the **onboarding flow** for the Appnomix SDK is currently available. (e.g. is was previously completed)
if (AppnomixCSDK.isOnboardingAvailable()) {
// calling this will launch the onboarding, only if it wasn't finished before. if it has, it's a no-op
AppnomixCSDK.showOnboarding(this)
}
}
}
Should you require more control or if you'd like to further fine-tune the onboarding experience for your users, you can also make use of the following functions the SDK is exposing:
AppnomixCSDK.isAccessibilityServiceEnabled-> returnstrueif the service is enabledAppnomixCSDK.goToToAccessibilitySettings-> takes the user to the OS Accesibility Settings, directly where the needed permission, without needing to launch the onboarding flow.
You can customize the colors on the onboarding screen by passing a string JSON, similar to the one from the sample app via AppnomixCSDK.showOnboarding(activity, jsonString).
What's next
If the integration is successful and the user has granted Accessibility Permission, then upon visiting a website in the Chrome browser where the SDK identifies valid deals and can interact with the HTML selectors, the user may see the following elements appear on their screen.
Event Tracking
Event Listeners
Should your app require more granular control regarding the SDK's onboarding process, you can register an event listener which will fire when the onboarding is started, finished, or abandoned:
AppnomixCSDK.registerEventListener(object : AppnomixEventListener {
override fun onAppnomixEvent(event: AppnomixEvent) {
when (event) {
AppnomixEvent.ONBOARDING_STARTED -> {
Log.i("AppnomixSample", "User started Appnomix Onboarding")
}
AppnomixEvent.ONBOARDING_ABANDONED -> {
Log.i(
"AppnomixSample",
"User left Appnomix Onboarding without activating the extension"
)
}
AppnomixEvent.ONBOARDING_FINISHED -> {
Log.i(
"AppnomixSample",
"User left Appnomix Onboarding and the extension is Activated"
)
}
}
}
})Tracking Offer Display
When presenting the offer to your users (e.g., as part of a list that includes Appnomix among other providers), you should call the following function to ensure accurate funnel tracking. The function accepts a string parameter representing the context in which the offer was shown, such as "home screen", "special offers", "level complete", or "daily rewards" based on what's relevant to your app.
AppnomixCSDK.trackOfferDisplay("home_screen")Installation Verification
To detect successful installation and track it, use AppnomixCSDK.isAccessibilityServiceEnabled which returns true if the Accessibility Service permission is granted for the app.
if (AppnomixCSDK.isAccessibilityServiceEnabled) {
// Extension is active
}Customization
UI Customization
The SDK supports customizing the UI of the onboarding flow by passing an optional JSON string via showOnboarding function.
You can customize the values of that JSON yourself or you can use the Appnomix UI Configurator to tweak the UI as you see fit, which will automatically generate the JSON.
Note: The web configurator renders a mocked UI to aid in getting a better sense of how the changes might look on a real device.
Once you have finished editing the JSON file, you can feed it as a string parameter to showOnboarding. It's up to the application how it will store that JSON (it can be stored as a file and loaded at runtime or you can store it as a string value).
Should you need to further customize the onboarding UI or other elements of the SDK that are not covered by the JSON, please reach out to us at [email protected].
Language Selection
The SDK accepts ISO 639-1 language codes through its initialize function. Currently, only "en" and "de" are supported. If no language code is provided, the SDK defaults to "en".
import android.app.Application
import app.appnomix.sdk.external.AppnomixCSDK
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
AppnomixCSDK.initialize(
authToken = "token_received_from_appnomix",
clientId = "clientId_received_from_appnomix",
options = AppnomixCSDK.ConfigurationOptions(
language = "de"
)
)
}
}API Reference
Functions
| Function | Parameters | Returns | Description |
|---|---|---|---|
initialize | authToken: StringclientId: Stringoptions: ConfigurationOptions? | Unit | Initializes the SDK by passing the auth data and language code |
registerEventListener | listener: AppnomixEventListener | Unit | Registers a listener for the onboarding lifecycle events |
trackOfferDisplay | context: String - A string identifying the screen or situation where the offer is displayed | Unit | Should be invoked, with a string context (e.g. "home_screen"), to aid in user funnel tracking |
showOnboarding | activity: ActivityjsonString: String? (optional) | Unit | Launches the SDK onboarding flow, required for enabling the Android Accessibility Service |
isAccessibilityServiceEnabled | None | Boolean | Checks whether the Android Accessibility Service permission is granted for the app |
isOnboardingAvailable | None | Boolean | Checks whether the onboarding flow for the Appnomix SDK is currently available |
goToAccessibilitySettings | activity: Activity | Unit | Takes the user to the OS Accessibility Settings directly |
Events
| Event | Description |
|---|---|
AppnomixEvent.ONBOARDING_STARTED | Triggered when the onboarding screen is shown |
AppnomixEvent.ONBOARDING_ABANDONED | Triggered if onboarding is exited early |
AppnomixEvent.ONBOARDING_FINISHED | Triggered when onboarding completes and extension is activated |
Testing & Support
Attribution Testing
To ensure that the SDK integration is working correctly and that attribution is being tracked properly, please contact us at [email protected]. We can verify that:
- Events are being tracked correctly
- User attribution is working as expected
- The integration is configured properly
What's Next
If the integration is successful and the user has granted Accessibility Permission, when visiting supported websites in Chrome, users will see:
- Automatic coupon detection and application
- Product price comparison (v2.0+)
- Product availability tracking (v2.0+)
- Deal notifications
Troubleshooting
Common Issues
If you encounter issues during integration, check the following:
-
Accessibility Service not enabled
- Verify that the user has completed the onboarding flow
- Use
AppnomixCSDK.isAccessibilityServiceEnabledto check the permission status - Use
AppnomixCSDK.goToAccessibilitySettings(activity)to direct users to the settings
-
Onboarding not showing
- Verify
AppnomixCSDK.isOnboardingAvailable()returnstrue - Check that your
clientIdandauthTokenare correct - Ensure
AppnomixCSDK.initialize()is called in your Application'sonCreate()before attempting to show onboarding
- Verify
-
Events not tracking
- Verify that
trackOfferDisplayis being called with a valid context string - Check that the SDK has been initialized before calling tracking functions
- Contact [email protected] to verify server-side tracking
- Verify that
-
Play Console submission issues
- Ensure you have completed the Accessibility Service declaration in Play Console (see Privacy & Permissions)
- Verify that your app's use case for Accessibility Service is properly documented
Error Codes
The SDK logs error codes to help diagnose integration issues. All errors are logged to the console, and critical errors are reported to Appnomix servers to help diagnose integration issues.
SDK Initialization Errors (E101-E105)
These errors occur when the SDK fails to initialize properly.
| Error Code | Message | Solution |
|---|---|---|
E101 | SDK init failed: missing clientId or authToken | Ensure both clientId and authToken are provided to initialize() |
E102 | SDK init: Config request timed out | Check your network connection; the SDK will retry automatically |
E103 | Config received but API usage is blocked remotely | Contact [email protected] - your account may be need to be setup |
E104 | SDK init: Received malformed config | Contact [email protected] with error details |
E105 | SDK init: Cannot schedule async jobs | Check that your app has proper background execution permissions |
Onboarding Errors (E201-E205)
These errors occur during the onboarding flow when users are setting up the Accessibility Service.
| Error Code | Message | Solution |
|---|---|---|
E201 | Onboarding failed to open: missing clientId/authToken | Ensure initialize() was called before showOnboarding() |
E202 | Onboarding failed to open: extension already enabled | The Accessibility Service is already enabled - no action needed |
E203 | Onboarding opened again: already completed | User has already completed onboarding - consider checking isOnboardingAvailable() first |
E204 | Onboarding failed to open: SDK config not received | Wait for SDK initialization to complete before showing onboarding |
E205 | Onboarding failed to open: SDK API disabled remotely | Contact [email protected] - your account may be need to be setup |
Network & Data Errors (E400-E404)
These errors occur during network requests or data processing.
| Error Code | Message | Solution |
|---|---|---|
E400 | Data: Bad request | Check SDK version compatibility; contact [email protected] if issue persists |
E401 | Network: Request timeout | Check network connectivity; the SDK will retry automatically |
E402 | Data: Deserialization error | Contact [email protected] - possible API change |
E403 | Data: Max retry reached | Network issue preventing data sync; will retry on next app launch |
E404 | Validation: validation failed | Contact [email protected] with the full error message including validation details |
Note: For any errors not listed here or if you need additional assistance, please contact [email protected] with the error code and relevant details from your logs.
Privacy & Permissions
Play Console Accessibility Service Declaration
Before submitting your app to the Play Store, you must complete the Accessibility Service declaration in the Play Console. This is required for all apps using android.permission.BIND_ACCESSIBILITY_SERVICE.
Steps to declare Accessibility Service usage:
- Log in to your Play Console
- Select your app
- Navigate to Policy > App content
- Find Accessibility and click Start
- Declare that your app uses Accessibility Services
- Provide the following information:
- Purpose: Select "Automated actions" or "Enhance user experience"
- Description: "This app uses Accessibility Services to detect active web pages in Chrome browser and automatically apply available discount codes and compare product prices, enhancing the shopping experience for users."
- Save and submit
For detailed guidance, refer to Google's official documentation: Accessibility Service declaration in Play Console
Required Permissions
The SDK automatically declares the following permission in its manifest:
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />No additional permissions need to be declared in your app's manifest.
Updated 25 days ago