MCA SDK Getting Started Guide

What is the MCA SDK?

The Mobile Cashback Alerts SDK offers a simple way to notify users when they visit eligible websites and provides a single-tap activation that allows users to earn from their purchases. The MCA SDK uses all the same Wildfire Systems merchant relationships and data to pop a heads-up notification and display the commission amount that a user is likely to earn from a given merchant.

 

mcagif

Recent Changes

  • 3.0.0.0 - Greater stability and resilience, easier to use (not yet released, coming soon!)
    • Breaking Change: Added ability to set URL prefix and TC parameters as part of SDK init (instead of callbacks which were less reliable). This deprecates the ability to set these values via callback.
    • Fixed edge-case crash when too many domains were loaded at once
    • Fixed encoding issues for some URLs
  • 2.1.1.0 - Resolved crashing bug related to storing very large merchant domain lists. 
  • 2.1.0.0 - Updated requestSecurityDialog() method to take a callback in response to request for back stack handling
  • 2.0.0.0
    • Automatically bring the user back to host app upon granting Accessibility permission so they don't need to find their way back to the host app
    • Breaking Change: Fixed misspelling of isAccessiblilityEnabled method
    • Breaking Change: Use non-vanity URLs for default activation links (which implies "&tc=" instead of "?tc=")
  • 1.0.0.11 - Use an alternate URL in the notification (this also deprecates the addParamsToVanity method); Hide the Share+Earn action

  • 1.0.0.9 - Improved passing previously created Device object

  • 1.0.0.8 - TC parameter support

  • 1.0.0.7 - Customizable Accessibility screen strings

Pre-requisites

  • Minimum Android API level 21 (Lollipop 5.0)

  • Chrome for Android (webviews and other browsers are incompatible at this time)

Getting Started

Note that the following screenshots are from the Dolphin 2021.3.1 Patch 1 version of Android Studio.  Some features in Android Studio may be located in different places.

Setting Up Your Application

Create a new application as you normally would (in this example, we'll select an empty activity):

 
Screenshot 2022-12-09 at 1.45.52 PM
Screenshot 2022-12-09 at 1.48.32 PM

Add the JitPack repository to your settings.gradle project:

repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
Screen Shot 2022-06-22 at 11.42.08 AM

Select "Sync Now" and allow the dependency map to update.

Then, add the MCA SDK dependency to your build.gradle module:

implementation 'com.github.wildlink:android-mobile-cash-back-alert:2.1.1.0'
 
Screenshot 2022-12-09 at 3.54.39 PM

Select "Sync Now" again and allow the dependency map to update.

Main Application Code

The MCA SDK shows notifications to your users when they visit a website in Chrome that's eligible for earning. In order for the SDK to perform this task, it requires the Accessibility permission. Unlike other permission requests where a permission prompt happens inside the context of the host app, granting the Accessibility permission requires navigating to a settings page in Android's system settings. This section will cover how to create a path for the user to grant that access and get a first notification on a merchant website.

There are a few steps in this section to complete:

  1. Add the buttons to the MainActivity view
  2. Connect the buttons in the MainActivity view to their respective functions
  3. Create the custom application class where the MCA SDK is initialized
  4. Connect the custom application to the manifest file

For our demo application, we'll provide a simple button in the MainActivity that will take the user to the Accessibility screen (exercising the method provided by MCA SDK).

1. Add the buttons to the MainActivity view

Let's first add a button to our view. In activity_main.xml replace the TextView element and add the following Button element:

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button"
android:layout_width="240dp"
android:layout_height="94dp"
android:text="Grant Accessibility"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:layout_constraintVertical_bias="0.496" />
 
Screen Shot 2022-06-22 at 11.52.05 AM

Note: The toggle between the code view and design view has changed in recent versions of Android Studio (from the tabs near the bottom left of the code window to the icons at the top right in newer versions).  This screenshot uses the "Code" view.

2. Connect the buttons in the MainActivity

Next, we'll add the following code to the MainActivity.kt to connect the button to the MCA SDK's methods:

package com.example.cashbackdemo20221209

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import me.wildfire.mobilecashbackalert.MobileCashbackAlert

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

setEnableAccessibilityClickListener()
}

private fun setEnableAccessibilityClickListener() {
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
if (!MobileCashbackAlert.isAccessibilityEnabled(this)) {
MobileCashbackAlert.requestSecurityDialog(this) {
val intent = Intent(this, MainActivity::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
intent.action = Intent.ACTION_MAIN
intent.addCategory(Intent.CATEGORY_LAUNCHER)
this.startActivity(intent)
}
} else {
Toast.makeText(this, "Cashback enabled", Toast.LENGTH_LONG).show()
}
}
}

}

Note: Your "package" line at the beginning of the file should reflect your project (i.e. if you chose a different project name).

Also Note: You may notice that the imported library is showing an unresolved reference error (even though the import is valid as we added it to our gradle imports).  In some cases, the caching of external dependencies needs to be refreshed.  There are a few ways to do this, but the easiest way is often to use the File -> Invalidate Caches feature.  Selecting Invalidate and Restart usually resolves this issue.

Screenshot 2022-12-09 at 4.17.42 PM

3. Create the custom application class where the MCA SDK is initialized

Next, we'll configure the application apart from the UI thread to initialize the SDK with our application's credentials and we'll set our split with the user. Create a new Kotlin class by right-clicking on your application from the left panel in Android Studio. We'll call this new class MyApplication.

Now add the following code to this new class:

package com.example.cashbackdemo20221209

import android.app.Application
import me.wildfire.mobilecashbackalert.*
import me.wildfire.mobilecashbackalert.models.UrlData

class MyApplication : Application(){
    companion object {
        lateinit var clientInfo: ClientInfo
    }
    override fun onCreate() {
        super.onCreate()
        val urlData = getUrlData()
        clientInfo = ClientInfo(
            "CLIENT_APP_ID_GOES_HERE",
            clientSecret = "CLIENT_APP_SECRET_GOES_HERE",
            notificationData = NotificationData(),
            userSplit = 0.5,
            urlData = urlData
        )
        MobileCashbackAlert.init(this, clientInfo)
    }

    private fun getUrlData(): UrlData {
        val urlData = UrlData()
        urlData.activateUrlTrackingCode = "ActivateTCValue"
        urlData.shareUrlTrackingCode = "ShareTCValue"
        return urlData
    }
}

There are a few things to explain here for the settings we're using that you'll want to come back to later.

App credentials: Be sure to replace the placeholders (i.e. CLIENT_APP_ID_GOES_HERE) with your actual Application's client ID and secret (contact your Wildfire Systems account manager if you need these values). 

User split: In the userSplit value, we use 50/50 in this example. We assume that you may want to take a portion of the user's earnings as part of your business model. If you wanted to pass the entire earnings along to the user then you would set this value to 1. If you wanted to take 75% of the user's earnings you would set this value to 0.25, and so on. This split is just between you and your user. The split agreement you have with Wildfire Systems is already accounted for before this split is applied. 

TrackingCode: This feature is new in v3.0.0.0. In the urlData.activateUrlTrackingCode value we've set a Tracking Code value that will always get passed as part of activation. Similarly, if the user select to share from the notification instead of activating cashback for themselves, the ShareTCValue value will be passed as the Tracking Code value. These Tracking Code values are returned as part of a commission record so you will know to attribute the earnings to. There is a separate article about Tracking Code (TC) Parameter values if you'd like to learn more.

Screenshot 2022-12-09 at 4.34.21 PM

4. Connect the custom application to the manifest file

Finally, before we run our application, we have to tell Android about our application class so that it knows how to reference it. In your AndroidManifest.xml add the following attribute to the application tag:

android:name=".MyApplication"
Screenshot 2022-12-09 at 4.35.53 PM

Note: Depending on your configuration, you may have build errors if you attempt to run your project at this point.  If you encounter this, check to ensure you're using JDK 11 and not JDK 1.8 for your Gradle configuration.  Under Android Studio > Preferences you'll find a section under Build, Execution, Deployment > Build Tools > Gradle where you may need to change from v1.8 to v11.

Screen Shot 2022-06-22 at 12.22.35 PM

Note: Depending on your target version of Android, you may need to adjust your build.gradle settings at this point. A common error that you may run into may look like this:

Dependency 'androidx.activity:activity:1.6.0' requires libraries and applications that
      depend on it to compile against version 33 or later of the
      Android APIs.

You can correct this by adjusting the targetVersion and compileSdk version to match the requirements described by this error message (i.e. moving from targetSdk 32 to 33).

Summary

You should now be able to:

  • Run your application

  • Select the button and be taken to the Accessibility screen

  • Grant permission (toggle Accessibility on)

  • Begin browsing in Chrome and receiving notifications for eligible web sites

The notifications contain two actions: Share & Earn which will invoke the native sharing dialog and populate it with a vanity URL (i.e. https://wild.link/walmart/abc123) and Activate Cashback, which will reload the user's current web page with cashback earning enabled.

Troubleshooting

If at this point you're able to run your project but you don't see notifications popping when you switch to an eligible website in Chrome (i.e. walmart.com, macys.com), there can be a few possible causes:

Invalid Wildfire credentials: Ensure that your client ID and secret are correct.  If these values are incorrect then the SDK will fail to fetch the eligible merchant domain list and it will not match any websites.  You can verify that this is the issue by filtering Logcat for "auth" and see if there are error messages like
errorMessage={"ErrorMessage":"Auth Signature Mismatch: App Auth did not match...

Notifications permission required: Android 13 adds new permissions for apps to send notifications to the user. This is very similar to the permission requests required by iOS. Some other Android makers (i.e. Xiaomi) may also require additional, explicit permission to send notifications. The good news is that these are "normal" permission requests and can be done in-app. Likely, your host app has other needs for notifications so you likely have prompted the user for this permission already. For the purposes of our demo app, add the following to your MainActivity, inside your onCreate function, to request permission at launch:

overridefun onCreate(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

setEnableAccessibilityClickListener()
Api().requestNotificationPermission()
}

Next Steps and Further Information

This is a simple example of how a host application can leverage the MCA SDK in order to give your users the ability to earn from their own purchases and the purchases of others. Because this system only works with the Accessibility permission granted, it's important to ensure that your users know why they should allow this permission and how to grant it. Amazon Assistant is a popular Android app that does a good job of describing this value proposition and shows the current status of the permission to the user.

The MCA SDK currently fires a notification anytime the user visits an eligible website and does not fire again until they change domains. For example, multiple pages viewed on Walmart.com will only fire a single notification (the first page view). Visiting Walmart.com and then another site and the Walmart.com again will fire the notification again. There is currently no further limiting of notifications.

Getting the Device ID from the SDK instance

Wildfire Systems performs all attribution to a Device ID. This is not tied to a hard device identifier like a serial number but rather it represents a generic client instance. As such, it does not persist across reinstalls on the same device. In order for your host app to carry through the attribution to your users, you'll need to take the generated Device ID and associate it to your user (i.e. in your backend data store). When the user grants the Accessibility permission, the MCA SDK broadcasts an event that can be caught with a broadcast receiver. Let's look at an example for how this works. Add the following code to your onCreate function in your MainActivity.kt:

 
// Define the broadcast receiver method
val deviceRegistrationListener = object: BroadcastReceiver(){
override fun onReceive(context: Context?, intent: Intent?) {
Log.d("foo", "deviceRegistrationListener - onReceive called")
intent?.let {
when (intent.action) {
Constants.ACTION_DEVICE_CREATED -> {
val device = it.getParcelableExtra<CbDevice>(Constants.KEY_DEVICE)
Log.d("foo", "device id = " + device?.deviceId)
}
else -> {
}
}
}
}
}

// Register the broadcast receiver
LocalBroadcastManager.getInstance(this).registerReceiver(deviceRegistrationListener,
IntentFilter(Constants.ACTION_DEVICE_CREATED))
)
Screenshot 2022-12-09 at 5.02.27 PM

This code defines a broadcast receiver (and registers it) that will be invoked when the user grants the Accessibility permission (even if they never return to your activity). This event will be fired after the device has been created in Wildfire Systems's backend and returned to the client, so you can safely retrieve the device.deviceId and then make a web request to store it in your backend.

Pausing and Resuming the Service

After we've received the Accessibility permission to run the URL matching service, the user may want to turn off the service from your host app for a time and resume it later. We want to avoid making the user go back into their settings, so we offer methods to pause and resume the service. When paused, the Accessibility permission is still enabled, but there's no evaluation of the user's URLs they visit, so they will not receive any notifications. Another UX option is to offer the user a single button to “pause notifications for 1 hour” where the host app could pause the service and start a timer to enable the service in an hour.

 
// to pause URL evaluation and notifications:
MobileCashbackAlert.disableUrlProcessing()
 
// to resume URL evaluation and notifications:
MobileCashbackAlert.enableUrlProcessing()

Customizing Notification Content

The following figure illustrates the customizable items:

If you would like to customize the notification messages to apply your own branding and messages, you may do so by overriding the default values like this in the MyApplication class:

var notificationData = NotificationData()
notificationData.titleText = "Earn on your {merchantName} purchases"
notificationData.largeViewLine1Text = "Or share and earn up to " + maxCommissionRate + "!!"
Screenshot 2022-12-09 at 5.20.20 PM

You can use the following variables either inline as curly braced tokens or as variables:

  • merchantName (i.e., Walmart)

  • maxCommissionRate (i.e., 2% or $2.50)

  • defaultCommissionRate (this is “the most likely earning rate” based on broadest product coverage vs. max which is the highest payout rate)

In addition to changing the default notification text, you can also change other properties, including the small and large icons of the notification. Here's a full list of the configurable properties:

Screenshot 2022-12-09 at 5.12.45 PM

Customizing Accessibility Setting Strings

When the user goes to the system settings to grant the Accessibility permission, there is an opportunity to describe the permission with a name and a description property. To do this, simply create values in your strings.xml to override the defaults:

<resources>
<string name="app_name">Cashback Demo</string>
<string name="cb_service_name">service name goes here</string>
<string name="cb_service_desc">service description goes here</string>
</resources>
 
Screenshot 2022-12-09 at 5.15.25 PM

Example of how these strings display:

Using the MCA SDK with a previously generated device

As of v1.0.0.9 the MCA SDK allows you to pass in a Device object. If your app has already generated a Wildfire Device ID (i.e., if you're using the Wildfire API Wrapper), then you should pass in this device to the MCA SDK so that a new device is not created. You may pass this reference in like so:

MobileCashbackAlert.setDevice(Device(wildfireDeviceJson))

The Device method allows you to pass in your previous generated and stored JSON for the device. When the MCA SDK receives a device in this way, it will not generate a new device when the MobileCashbackAlert.init() method is called.

Hiding the Share+Earn action

We recommend always giving users the option to share an affiliate link or activate cashback to maximize earning opportunities, but we also understand that sometimes a partner only wants to show a single appeal to their users. As of v1.0.0.11 the MCA SDK allows the host app to set a flag to hide the Share+Earn action from eligible merchant notifications. In the notificationData, set the disableShare property to true.

notificationData.disableShare = true

Now, when the notification fires, only the Activate Cashback action is shown to the user.

Known Issues

  • Motorola: Notifications don't show on Motorola devices due to inconsistencies in reporting of on-screen content. Motorola market share is about 3% of global Android devices.

  • Oppo: Notifications don't show on some Oppo devices (notifications are non-standard). Oppo market share is between 5-7% of global Android devices.