Tracking API

Updated at:

1. Tracking plan

Before implementing tracking, define your tracking requirements by determining what to track and where. In the QuickTracking platform, these requirements form a tracking plan. The platform provides a standard template for creating tracking plans, as shown below:

image

The instrumentation plan defines the content to be tracked:

1. principal: Identifies who triggered the event. Each reported event must include either a device ID or an account ID.

  • device ID: For Android devices, the default device ID is a unique, app-level identifier automatically generated by QuickTracking:

    • On devices running Android 9 or earlier, the SDK generates the device ID using imei, wifimac, androidid, and SN. This ID is stored locally and is regenerated only if the app is uninstalled or its data is cleared.

    • On devices running Android 10 or later, the SDK generates the device ID using oaid, gaid, androidid, and SN. This ID is stored locally and is regenerated only if the app is uninstalled or its data is cleared.

    • The QuickTracking SDK collects idfa and oaid only with end user consent. Only the QuickTracking SDK can collect identifiers such as oaid, gaid, imei, wifimac, androidid, SN, idfa, and idfv.

  • account ID: An identifier that represents a user after they log in. When a user logs in on different devices, such as a phone and a tablet, the device ID changes while the account ID remains the same.

2. User attribute: A property associated with an account ID. For example, for a user with the account ID "testdemo@111", their birthday could be "1999-02-13" and their membership level could be "Platinum".

3. Channel attribute: Characteristics of ad delivery, such as delivery channel, delivery method, and ad content.

4. Global property: A property that, when set globally, is automatically included with every event.

5. page view event: An event reported on page load (in a tracking plan, this event has identical page and event codes and is also marked in blue).

6. click, impression, and custom event: Events triggered by user interactions on the client.

2 Set device and account IDs

2.1 Device ID settings

The SDK's default implementation class, DefaultDeviceInfo in the com.quick.qt.commonsdk package, collects the following device identifiers by default.

Type

Parameter

API

Description

String

Android ID

String getAndroidID(Context context)

Android ID

String

serial number

String getSerial()

Android device serial number

String

IMEI

String getImei(Context context)

IMEI

String

IMSI

String getImsi(Context context)

IMSI

String

Wi-Fi MAC address

String getWifiMac(Context context)

Wi-Fi MAC address

String

OAID

String getOaid(Context context)

OAID (for the Chinese mainland)

String

GAID

String getGaid(Context context)

Google Advertising ID

String

MCC and MNC

String getMCCMNC(Context context)

MCC: Mobile Country Code

MNC: Mobile Network Code

Returns a concatenation of the MCC (3 digits) and MNC (2 or 3 digits). For example, 46011 represents MCC 460 and MNC 11.

int[]

resolution

getResolution

Screen resolution, returned as an array: [width, height]

String

CPU

getCPU

CPU information

To control the collection of specific device identifiers in the table above, such as not collecting the IMEI and serial number or implementing a custom OAID collection method, create a subclass of DefaultDeviceInfo and override the getImei, getSerial, and getOaid methods, as shown in the following example:

import com.quick.qt.commonsdk.DefaultDeviceInfo;

public class CustomDeviceInfo extends DefaultDeviceInfo {

	@Override
	public String getImei(Context context) {
		return null;
	}

	@Override
	public String getSerial() {
		return null;
	}

	@Override
	public String getOaid(Context context) {
		String oaid = "";
        // oaid = getOaidMethod(); // Your custom method for getting the OAID
        return oaid;
	}

}

The QuickTracking SDK collects the device identifier by default. If you override this method, you become solely responsible for collecting the identifier, as the SDK will no longer do so. Collecting fewer identifiers decreases the accuracy and stability of the statistics.

Registering custom tool classes

import com.quick.qt.commonsdk.QtConfigure;

// Call the function to register the collector tool class before setting the data collection service domain or calling the SDK pre-initialization function.
// If you do not need to control how device identifiers are collected, you do not need to implement and register a custom tool class.
QtConfigure.setDeviceInfo(new CustomDeviceInfo());
QtConfigure.setCustomDomain("Your data collection service domain", null);

You can set a custom device ID by calling setCustomDeviceId with a non-null value before calling init.

public static void setCustomDeviceId(Context var0, String var1)

Example:

import com.quick.qt.commonsdk.QtConfigure;

QtConfigure.setCustomDeviceId(this, "xxxxxx");

Note: This feature only takes effect if no local device ID exists. To test this, uninstall and reinstall the app.

2.2 Get device ID

You can get it as follows:

import com.quick.qt.commonsdk.QtConfigure;

QtConfigure.getUMIDString(this)

2.3 Account ID

1. By default, users are tracked on a per-device basis. To track users by their application account instead, use the following API:

public static void onProfileSignIn(String ID);

Parameter

Description

ID

The user account ID. Must be less than 64 bytes long.

Note: Once an account ID is set, it is saved to local storage and included with every subsequent event until you uninstall the app, clear its application data, or call the login API.

2. Call this API when signing out to stop sending content to the account.

public static void onProfileSignOff();

Example:

import com.quick.qt.analytics.QtTrackAgent;

// Tracks a user sign-in via your own account system.
QtTrackAgent.onProfileSignIn("userID");

// Tracks a user sign-off.
QtTrackAgent.onProfileSignOff();

3 Set user attributes

Report user attributes using the preset event code $$_user_profile.

Before you report user attributes, you must first set the user's account ID (_user_id). Otherwise, QuickTracking traffic analysis will be unable to associate the attributes with the user account. After the account ID is set, use the following example to report user attributes:

import com.quick.qt.analytics.QtTrackAgent;
import java.util.HashMap;
import java.util.Map;

Map<String, Object> user = new HashMap<String, Object>();
user.put("sex", "girl"); // Gender
user.put("age", "8");    // Age
QtTrackAgent.onEventObject(mContext, "$$_user_profile", user);

4. Channel attributes

4.1 Launch app from H5 link

Channel attributes do not require tracking. However, the URL that launches the mini program or app must include these attributes, and each attribute key must start with utm_, as this is the keyword the SDK recognizes. For example:

<url scheme>?utm_channel=gzh

Note: If you work with a third-party channel attribution provider and cannot use the utm_ prefix, use the global attribute API to send the channel attribute (the attribute key must still begin with utm_).

4.2 H5 link to download and launch app

If utm_ parameters exist only in the H5 link, they are not passed to the app activation event after installation. Therefore, you must fuzzy match the H5 app-launch event and the app activation event using their IP address and user agent.

  1. When a user clicks the "Wake up/Download App" button on an H5 page, report the app launch event ($$_app_link). The event must include the app key and the channel attribute.

// example
aplus_queue.push({
  action:'aplus.recordAppLink',
  arguments:[{
    targetAppKey: 'The appKey of the target application',  // required. The appKey of the target application.
    custom1: 'custom1', // optional. A custom parameter.
    ...
  }]
})
  1. The QT App SDK automatically collects and reports the app activation event ($$_app_install), which triggers on the app's first launch after download.

  2. The QuickTracking system performs fuzzy matching between the app link event ($$_app_link) and the app activation event ($$_app_install) using the IP address and browser User-Agent. This allows you to directly analyze the channel attributes for app activation (preset) in your app.

App activity statistics by app store

The third parameter in the initialization function, Channel, specifies the app market: QtConfigure.preInit(this, "YOUR_APP_KEY", "Channel-Huawei");, QtConfigure.init(this, "YOUR_APP_KEY", "Channel-Huawei", QtConfigure.DEVICE_TYPE_PHONE, "");

5 Global properties

After you register global attributes, they are automatically included in all subsequent events. These attributes and their values are stored in memory and cleared when the app is closed. Use these attributes to view and filter data.

5.1 Register a global attribute

This global method is available in any context, so you can call it without needing a Context object. The properties you set are then added to all subsequent events (including $pageview events).

The var1 parameter in the function signature public static void registerGlobalProperties(Context var0, Map<String, Object> var1); is used to set the global properties. This parameter is a Map. New properties will overwrite existing properties with the same key.

Parameter

Description

var0

The ApplicationContext of the current host process.

propertyName

The property name.

propertyValue

The property value.

Numeric types

Type

Example

Recognized type

Limitations

Number

12 or 12.0

<number (Integer, Long, Float, Short, Double)>

None

Boolean

true or false

<boolean>

None

String

"This is test Text"

<string>

The maximum length is 1,024 bytes after UTF-8 encoding. If this limit is exceeded, the system drops the field.

List

["ABC","123"]

<list>

By default, this is an array of string elements. Duplicate strings are not removed. The array supports a maximum of 100 elements. Each element has a maximum length of 255 bytes after UTF-8 encoding.

String

  • "2025-11-11 11:11:11.111"

  • "2025-11-11 11:11:11"

  • "2025-11-11"

<datetime>

The first format, which includes milliseconds (SSS), is recommended.

  • yyyy-MM-dd HH:mm:ss.SSS

  • yyyy-MM-dd HH:mm:ss

  • yyyy-MM-dd (time defaults to 00:00:00)

Note:

  1. Property names and string property values can only contain letters, numbers, and underscores.

  2. A property value must be one of the following Java types: String, Long, Integer, Float, Double, or Short.

  3. If a global property key already exists, its value is updated. Otherwise, a new global property is created.

    Example:

    import com.quick.qt.analytics.QtTrackAgent;
    import java.util.HashMap;
    import java.util.Map;
    
    Map firstMap = new HashMap<String, Object>();
    firstMap.put("a", "1");
    firstMap.put("b", "2");
    QtTrackAgent.registerGlobalProperties(mContext, firstMap); // Current global properties are a:1 and b:2.
    
    Map secondMap = new HashMap<String, Object>();
    secondMap.put("b", "3");
    secondMap.put("c", "4");
    QtTrackAgent.registerGlobalProperties(mContext, secondMap); // Current global properties are a:1, b:3, and c:4.

5.2 Delete a global attribute

public static void unregisterGlobalProperty(Context context, String propertyName);

Parameter

Description

context

The ApplicationContext of the host process.

propertyName

The property name. It can only contain uppercase and lowercase letters, digits, and underscores.

Example:

Removes a specific global property. Once removed, the property will no longer be included in subsequent events.

import com.quick.qt.analytics.QtTrackAgent;

QtTrackAgent.unregisterGlobalProperty(mContext, "lnch_Source");

5.3 Get global attribute by key

public static Object getGlobalProperty(Context context, String propertyName);

Parameter

Description

context

The ApplicationContext of the current host process.

propertyName

The property name. Valid characters are uppercase and lowercase letters, digits, and underscores.

Object (return value)

The global property value can be one of the following Java types: String, Long, Integer, Float, Double, or Short. This type must match the type specified when the property was registered.

Example

import com.quick.qt.analytics.QtTrackAgent;

String userId = QtTrackAgent.getGlobalProperty(mContext, "lnch_Source");

5.4 Global attributes

public static String getGlobalProperties(Context context);

Parameter

Description

context

The ApplicationContext for the current host process.

string (return value)

Returns a JSON string containing all global properties as key-value pairs. For example: {"id":"SA1375","userName":"Mike","account_type":"vip", "MemberLevel":"Level1"}

Example:

import com.quick.qt.analytics.QtTrackAgent;

String allSuperProp = QtTrackAgent.getGlobalProperties(mContext);

5.5 Clear global attributes

public static void clearGlobalProperties(Context context);

Parameter

Description

context

The ApplicationContext for the current host process.

Example:

import com.quick.qt.analytics.QtTrackAgent;

QtTrackAgent.clearGlobalProperties(mContext);

6 Page view event API

6.1 Manual collection via console

To track page paths and duration for Activities, Fragments, CustomViews, and other custom pages, developers can add manual instrumentation by calling QtTrackAgent.onPageStart and QtTrackAgent.onPageEnd.

public static void onPageStart(String viewName);
public static void onPageEnd(String viewName);

Parameter

Description

viewName

The name of the custom page.

The following sample code shows how to manually track the page path of a fragment:

import com.quick.qt.analytics.QtTrackAgent;

// A pair of onPageStart() and onPageEnd() calls tracks the lifecycle of a non-Activity page (for example, a Fragment).

// Override the onResume method of the Fragment.
public void onResume() {
    super.onResume();
    QtTrackAgent.onPageStart("MainScreen"); // Tracks the page using a customizable page ID ("MainScreen").
}

// Override the onPause method of the Fragment.
public void onPause() {
    super.onPause();
    QtTrackAgent.onPageEnd("MainScreen");
}

Note:

The onPageStart method records the start of a page view but does not report an event; calling the onPageEnd method reports the page view event.

Calls to onPageStart and onPageEnd must be paired and use an identical page_name value. Otherwise, the data from onPageStart is discarded.

6.1.1 Page attribute upload

The QtTrackAgent.setPageProperty() method sets a custom property for the current page.

API: QtTrackAgent.setPageProperty

Parameters:

Parameter

Description

context

The context of the current application.

pageName

The name of the target page. This value must match the name of the current page. The function has no effect if the names do not match.

pageProperty

The key-value pairs to associate with the page. The value can be a String, Integer, Long, Float, Short, or Double.

Example:

This example shows how to set properties for the current page when the Activity becomes visible:

import com.quick.qt.analytics.QtTrackAgent;

private static final String PAGE_NAME = "page_home"; // The identifier for the home page.
 
 @Override
 public void onResume() {
    super.onResume();
   
    QtTrackAgent.onPageStart(PAGE_NAME); // Starts tracking this page view.
    Map<String, Object> params = new HashMap<>();
    params.put("home_param_1", "value11"); // Add a custom property for the page.
    QtTrackAgent.setPageProperty(mContext, PAGE_NAME, params);
 }

Note: Page attributes support only manual event tracking.

6.1.2 Passthrough page properties

Additionally, the QuickTracking SDK provides the SpmAgent.updateNextPageProperties interface for attaching custom properties to the next page.

API: SpmAgent.updateNextPageProperties

parameter:

Parameter

Description

params

A map of key-value pairs. Each value can be a String, Integer, Long, Float, Short, or Double.

Supported types:

Type

Value

Recognized type

Limitations

number

12 or 12.0

<number (Integer, Long, Float, Short, Double)>

None

boolean

true or false

<boolean>

None

string

"This is test Text"

<string>

The maximum length is 1,024 bytes after UTF-8 encoding. Fields exceeding this limit are discarded by the system.

list

["ABC","123"]

<list>

By default, a list is an array that can contain up to 100 string elements. Duplicates are allowed. Each element has a maximum length of 255 bytes after UTF-8 encoding.

string

  • "2025-11-11 11:11:11.111"

  • "2025-11-11 11:11:11"

  • "2025-11-11"

<datetime>

We recommend the first format, which provides millisecond precision (SSS).

  • yyyy-MM-dd HH:mm:ss.SSS

  • yyyy-MM-dd HH:mm:ss

  • yyyy-MM-dd (The time component defaults to 00:00:00)

/**
*
* Called when navigating to the next page.
*/
public static void updateNextPageProperties(Map<String, Object> params)

Value-passing example:

import com.quick.qt.analytics.QtTrackAgent;
import com.quick.qt.spm.SpmAgent;

public class MainActivity extends AppCompatActivity {
    private static final String PAGE_NAME = "page_home";
    private Button mGoNewsWithHole;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setTitle("QuickTracking Analytics Home Page");
        setContentView(R.layout.activity_u4a_home);

        binding.btnGoToDetail.setOnClickListener(v -> {
            // Pass custom attributes to the next page
            Map<String, Object> params = new HashMap<>();
            params.put("my_transfer_arg1", "Passthrough attribute value from MainActivity");
            SpmAgent.updateNextPageProperties(params);
            startActivity(new Intent(this, DetailActivity.class));
        });
    }
 }

Example value:

import com.quick.qt.spm.SpmAgent;

String transferValue = SpmAgent.getPageProperty(PAGE_NAME, "my_transfer_arg1", SpmAgent.transProperties);

Note: Pass-through page attributes are only supported for manual tracking.

Complete example

PageA

package com.quick.qt.u4ademo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.quick.qt.spm.SpmAgent;

import java.util.HashMap;
import java.util.Map;

public class TestPageA extends Activity {
    private Context mContext;
    private static final String PAGE_NAME = "pv_a";

    private Button mJumpToPageB;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_page_a);

        mContext = this;
        mJumpToPageB = (Button) findViewById(R.id.btn_jump_to_page_b);
        mJumpToPageB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 1. Pass custom properties to Page B.
                Map<String, Object> params = new HashMap<>();
                params.put("my_transfer_arg1", "parameter value 1 to pass");
                params.put("my_transfer_arg2", 123);
                SpmAgent.updateNextPageProperties(params);

                // 2. Navigate to Page B.
                startActivity(new Intent(mContext, TestPageB.class));

                // 3. Track the click event with custom properties.
                Map<String, Object> clickParams = new HashMap<>();
                clickParams.put("buttonID", "Button_jump");
                QtTrackAgent.onEventObject(mContext, "a_position_click", clickParams);
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        // Start the PV event for Page A.
        QtTrackAgent.onPageStart(PAGE_NAME);
    }

    @Override
    public void onPause() {
        super.onPause();
        // End the PV event for Page A.
        QtTrackAgent.onPageEnd(PAGE_NAME);
    }
}

PageB

package com.quick.qt.u4ademo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.quick.qt.spm.SpmAgent;

import java.util.HashMap;
import java.util.Map;

public class TestPageB extends Activity {
    private Context mContext;
    private static final String TAG = "TestPageB";
    private static final String PAGE_NAME = "pv_b";

    private Button mJumpToPageC;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_page_b);
        mContext = this;
        mJumpToPageC = (Button) findViewById(R.id.btn_jump_to_page_c);
        mJumpToPageC.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              // Get the property values passed from the previous page.
              String stringValue = SpmAgent.getPageProperty(PAGE_NAME, "my_transfer_arg1", "");
              Integer intValue = SpmAgent.getPageProperty(PAGE_NAME, "my_transfer_arg2", 0);
              Log.i(TAG, "Received from previous page - stringValue: " + stringValue + ", intValue: " + intValue);
            }
        });
    }
}

6.2 Autotrack activity pages

Automatic data collection for Activity pages is enabled by default, so you do not need to integrate the autotrack gradle plugin. The SDK automatically collects the page path and visit duration for each Activity page. If you also call the manual QtTrackAgent.onPageStart/onPageEnd APIs, this will cause duplicate data reporting. To prevent this, call the QtTrackAgent.disableActivityPageCollection() function immediately after the QtConfigure.preInit function to disable the SDK's automatic data collection for Activity pages.

public static void disableActivityPageCollection();

To disable automatic collection and reporting for a specific activity, call this function in its onCreate method:

import com.quick.qt.analytics.QtTrackAgent;

QtTrackAgent.skipMe(this, null); 

Parameter

Type

Description

this

Activity object

The WebView host Activity object. Pass this to stop reporting automatic page data for the current page.

viewName

string

The custom page code for manual instrumentation. Pass an empty string to report manual instrumentation data for the current page, or pass a custom page code to stop reporting it.

6.3 Auto-tracking on fragment pages

By default, auto-tracking is disabled for Fragment pages. To enable it, you must integrate the codeless tracking plugin and turn on the auto-tracking switch. For details, see

8.1 Integrate the autotrack gradle plugin, then enable autotrack for fragment PVs.

7 Event tracking

Use custom events to track user behavior and record interaction details.

7.1 Event tracking

To track events, use the onEventObject interface. Its parameter can be a String, Long, Integer, Float, Double, or Short.

Interface:

public static void onEventObject(Context context, String eventID, Map<String, Object> map)

public static void onEventObject(Context context, String eventID, Map<String, Object> map, String pageName)

Parameter

Description

context

The ApplicationContext of the current host process.

eventId

The ID of the event to track.

map

A HashMap of key-value pairs that represent the event parameters.

pageName

The name of the page where the event occurred.

Event upload limit:

  • A custom attribute key cannot exceed 1,024 characters.

  • A custom attribute value cannot exceed 4,096 characters.

  • A custom attribute map can contain up to 100 key-value pairs.

  • If a custom attribute value is an array, it can contain up to 100 elements.

Numeric types:

Type

Example

Recognized type

Restrictions

Number

12 or 12.0

<Number (Integer, Long, Float, Short, Double)>

None

Bool

true or false

<Bool>

None

String

"This is test Text"

<String>

The maximum length is 1,024 bytes after UTF-8 encoding. If a field's value exceeds this limit, the system drops the field.

List

["ABC","123"]

<List>

A list of String elements. The list preserves duplicate elements. The list is limited to 100 elements, and each element can be up to 255 bytes long after UTF-8 encoding.

String

  • "2025-11-11 11:11:11.111"

  • "2025-11-11 11:11:11"

  • "2025-11-11"

<Datetime>

We recommend using the first format, where SSS represents milliseconds.

  • yyyy-MM-dd HH:mm:ss.SSS

  • yyyy-MM-dd HH:mm:ss

  • yyyy-MM-dd (The time component defaults to 00:00:00)

Example:

import com.quick.qt.analytics.QtTrackAgent;

Map<String, Object> music = new HashMap<String, Object>();
music.put("music_type", "popular"); // custom parameter: music type
music.put("singer", "JJ"); // Artist: JJ (Lin Junjie)
music.put("song_name","A_Thousand_Years_Later"); // Song title: A Thousand Years Later
music.put("song_price",100); // Price in CNY
QtTrackAgent.onEventObject(this, "play_music", music, "home_page");

Note:

  • The 'event sampling rate' configuration depends on the 'auto-event switch', which is controlled using the 'setAutoEventEnabled()' method.

    Example:

    public class MyApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
    	QtConfigure.setCustomDomain("Your data collection service domain", null);
            // Enable the debug log.
            QtConfigure.setLogEnabled(true);
            // The event sampling rate depends on the auto-event switch. Call setAutoEventEnabled() to control this switch.
            QtTrackAgent.setAutoEventEnabled(false);        
            //...
        }
        //... 
    }
  • A 'multi-parameter type event' covers the same analysis scenarios as 'calculation events' and 'counting events'.

  • For 'computational events', the calculation method depends on the 'parameter type', which can be either numeric or character.

    • Numeric: Supports 'cumulative value', 'maximum value', 'minimum value', 'average value', and 'distinct count'.

    • Character: Supports 'distinct count'.

7.2 Child process instrumentation

The SDK only supports custom event tracking for child processes; other data collection types, such as page tracking, are not supported. To enable event tracking in a child process, call QtConfigure.setProcessEvent after initializing the SDK.

Example:

public class MyApplication extends Application{
    @Override
    public void onCreate(){
        super.onCreate();
        // Initialize the SDK
        QtConfigure.preInit(this, "your app key", "app marketplace");
        
        // Enable custom event tracking in child processes
        QtConfigure.setProcessEvent(true);
        // ...

Note:

  • Initialize the SDK in any child process where you need to track custom events.

Duration events

SDK 1.9.1.PX+ introduces a duration-type event. You can control the timer's lifecycle (start, pause, resume, and end), and the SDK will automatically exclude the pause duration, calculate the effective playback duration, and report the event with custom attributes.

API:

 /**
   * Starts a duration event.
   *
   * @param context The current context.
   * @param eventID The event ID.
   * @return A unique timer ID for managing the timer.
 */
public static String eventTimerStart(Context context, String eventID)

/**
   * Ends the specified event timer and reports the statistics.
   *
   * @param timerID The timer ID.
   */
public static void eventTimerEnd( String timerID)

 /**
   * Pauses the specified event timer.
   *
   * @param timerID The timer ID.
   */
public static void eventTimerPause(String timerID) 

 /**
   * Resumes the specified event timer.
   *
   * @param timerID The timer ID.
   */
public static void eventTimerResume(String timerID) 

/**
 * Sets properties for the specified event timer.
 *
 * @param timerID    The timer ID.
 * @param properties The properties for the timer.
 */
public static void setTimerProperties(String timerID, Map<String, Object> properties) 

7.3.1 Start timer (eventTimerStart)

Call this method when an event starts. It generates a unique id and starts a scheduled background save task.

Parameter

Type

Description

context

context

The ApplicationContext of the current host process.

eventId

String

The ID of the event to track.

Return value

String

A unique ID.

Example:

String playId = QtTrackAgent.eventTimerStart(this,"video_play");

7.3.2 Set timer properties (setTimerProperties)

Sets metadata for the event, such as a title, URL, or type. This method can be called anytime after the event starts and before it ends.

Parameter

Description

playId

The unique ID returned by the event.

props

Event properties, as described below.

Event upload limit:

  • The maximum length of a custom attribute key is 1,024 characters.

  • The maximum length of a custom attribute value is 4,096 characters.

  • A map used as a custom attribute value can contain up to 100 key-value pairs.

  • An array used as a custom attribute value can contain up to 100 elements.

Numeric types

Type

Example

Recognized type

Restrictions

number

12 or 12.0

<number (Integer, Long, Float, Short, Double)>

None

boolean

true or false

<boolean>

None

string

"This is test Text"

<string>

The maximum length is 1024 bytes after UTF-8 encoding. If the value exceeds this limit, the system discards the current field.

list

["ABC","123"]

<list>

An array of string elements where duplicates are allowed. The list is limited to 100 elements, and each element has a maximum length of 255 bytes after UTF-8 encoding.

datetime

  • "2025-11-11 11:11:11.111"

  • "2025-11-11 11:11:11"

  • "2025-11-11"

<datetime>

The first format is recommended, where SSS represents milliseconds.

  • yyyy-MM-dd HH:mm:ss.SSS

  • yyyy-MM-dd HH:mm:ss

  • yyyy-MM-dd (Time defaults to 00:00:00.)

Example:

Map<String, String> props = new HashMap<>();
props.put("video_id", "10086");
props.put("video_title", "Test Video");
props.put("category", "movie");
QtTrackAgent.setTimerProperties(playId, props);

7.3.3 Pause the timer (eventTimerPause)

Called when the video pauses or buffers. Subsequent calls are ignored and do not accumulate the pause time.

Parameter

Type

Description

playId

String

The unique ID returned by the current event.

Example:

QtTrackAgent.eventTimerPause(videoUuid);

7.3.4 Resume timer (eventTimerResume)

Call this method when the user resumes playback or when buffering is complete. Subsequent calls are ignored.

Parameter

Type

Description

playId

String

The unique ID returned by the current event.

Example:

QtTrackAgent.eventTimerResume(videoUuid);

7.3.5 End and report (eventTimerEnd)

Call this method when the video finishes playing, the user closes the page, or the user switches videos.
This method does the following:

  1. Calculate the effective playback duration in milliseconds.

  2. Build the JSON data for reporting.

  3. Trigger the reporting callback (requires integration with your own analytics solution).

  4. Remove the task from local storage and memory.

Parameter

Type

Description

playId

String

The unique ID for the event.

QtTrackAgent.eventTimerEnd(videoUuid);

7.3.6 Event persistence interval (setEventTimeInterval)

Configure the automatic data sinking interval. The value can range from 1 to 300 s, with a default of 15 s.

Parameter

Type

Description

interval

int

The interval for persisting data, in milliseconds.

API

public static void setEventTimeInterval(int interval);

Example:

QtConfigure.setEventTimeInterval(3 * 1000);

7.3.7 Duration event background listener

SDK 1.9.3.PX+ allows you to monitor the background playback duration.

Configuration method

package com.quick.qt.analytics.timeevent;

public enum BGDurationMode {
    Disabled, // Disables background duration tracking (default).
    Automatic, // Tracks duration automatically based on the SDK's foreground/background state switching (`app_start` and `app_end`).
    Manual; // Requires manual duration tracking.
}

Initialization APIs:

/**
 * Sets the mode for background event duration.
 *
 * @param mode The mode to set.
 */
public static void setEventTimeBgMode(BGDurationMode mode)

Set the configuration using the following method before SDK initialization.

QtConfigure.setEventTimeBgMode(BGDurationMode.Manual);

A new API now supports manual mode. The following code is only effective in manual mode:

/**
 * Manually sets the state to the foreground (called by developers in manual mode).
 *
 */
public static void setEventTimerToForeground();

/**
 * Manually sets the state to the background (called by developers in manual mode).
 *
 */
public static void setEventTimerToBackground();
...
// manual switch to foreground
btnToForeground.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        appendLog("Manual switch to foreground");
        QtTrackAgent.setEventTimerToForeground();
    }
});

// manual switch to background
btnToBackground.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        appendLog("Manual switch to background");
        QtTrackAgent.setEventTimerToBackground();
    }
});
...

8 Codeless tracking

8.1 Codeless tracking Gradle plugin

Older Gradle versions

In the project-level build.gradle file, add the plugin dependency:

Note

Note:

  • The Android Plugin requires AGP 3.2.0 or later. Otherwise, element click events and Fragment page view events will not trigger.

buildscript {
    repositories {
        maven { url 'https://repo1.maven.org/maven2/' } // QuickTracking repository
        jcenter()
            google()
        }
    
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.4'
            
            // Add the QuickTracking android-gradle-plugin dependency.
            // For Gradle versions below 7.1.2
            //classpath 'com.umeng.umsdk:android-gradle-plugin:1.0.0' 
            // For Gradle versions from 7.1.2 to 7.5
            classpath 'com.lydaas.qtsdk:quick-gradle-plugin2:1.0.2'
            // For Gradle versions from 7.5 to 8.x
            // classpath 'com.lydaas.qtsdk:quick-gradle-plugin2:2.0.0'
            // For Gradle versions 9.0 and later
            // classpath 'com.lydaas.qtsdk:quick-gradle-plugin2:2.0.1'
        }
}

allprojects {
    repositories {
        maven { url 'https://repo1.maven.org/maven2/' } // QuickTracking repository
        jcenter()
            google()
        }
}

AGP 7.0 and later

In your project's settings.gradle file, add the repository URL:

pluginManagement {
    repositories {
        google {
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
        maven { url 'https://repo1.maven.org/maven2/' }// QuickTracking repository
    }

}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://repo1.maven.org/maven2/' }// QuickTracking repository
    }
}

In your main module's build.gradle file, add the plugin dependency:

buildscript {
    dependencies {
        classpath 'com.lydaas.qtsdk:quick-gradle-plugin2:2.0.1'
    }
}
Note

Note:

  • In the gradle.properties file in the app's root project directory, append -noverify to the org.gradle.jvmargs parameter value.

  • If the app's root project directory does not have a gradle.properties file, create one. If this file lacks the org.gradle.jvmargs parameter, add the parameter and set its value to -noverify.

image.png

8.2 Dependency management with the Gradle build plugin

Apply the auto-tracking plugin in your main module's build.gradle file:

apply plugin: 'com.android.application'
//apply plugin: 'com.qt.analytics.plugin' // P version plugin (for codeless tracking)
apply plugin: 'com.quick.analytics.plugin' // PX version plugin (for codeless tracking)

dependencies {
   // Add the QuickTracking analytics SDK. The SDK version must match the gradle plugin version above.
   //implementation 'com.umeng.umsdk:qt-common:1.4.4.P' // P version (SDK version format: x.x.x.P)
   implementation 'com.lydaas.qtsdk:qt-px-common:1.8.6.PX'  // PX version (SDK version format: x.x.x.PX)
}

8.3 Autotrack API

8.3.1 Autotrack switch

Fragment PV autotracking

To enable automatic collection of page view events for all fragments, call enableFragmentPageCollection().

/**
* Enables or disables automatic data collection for Fragment pages. This feature is disabled by default.
* @param enable `true` to enable; `false` to disable.
*/
public static void enableFragmentPageCollection(boolean enable);

Example:

import com.quick.qt.commonsdk.QtConfigure;
import com.quick.qt.analytics.QtTrackAgent;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
	QtConfigure.setCustomDomain("Your data collection domain", null);
        // Enable debug logging.
        QtTrackAgent.enableFragmentPageCollection(true);
        //...
    }
    //... 
}
Activity PV data

Automatic Activity page collection is enabled by default. During a session, the SDK automatically collects and reports the page path and visit duration for each Activity. If you also call the manual page path collection APIs, QtTrackAgent.onPageStart and QtTrackAgent.onPageEnd, this will cause duplicate reporting. To prevent this, call the QtTrackAgent.disableActivityPageCollection() function immediately after the QtConfigure.preInit function.

public static void disableActivityPageCollection();

To disable automatic collection and reporting for an activity, call this function from its onCreate method:

import com.quick.qt.analytics.QtTrackAgent;

QtTrackAgent.skipMe(this, null); 
Disable automatic page collection

To disable automatic collection and reporting for a specific activity, call the following method in that activity's onCreate method:

import com.quick.qt.analytics.QtTrackAgent;

QtTrackAgent.skipMe(this, null); 

Parameter

Type

Description

this

Activity object

The WebView host Activity object. Pass this object to disable automatic page data reporting for the current page.

viewName

string

The custom page code for manual instrumentation. To disable reporting for the page associated with this code, pass the code. Reporting is enabled by default.

Control click autotracking
/**
 * Enables or disables the automatic collection of control click events.
 * Disabled by default.
 * @param enable `true` to enable automatic collection; `false` to disable.
 */
public static void setAutoEventEnabled(boolean enable);

Example:

import com.quick.qt.analytics.QtTrackAgent;
import com.quick.qt.commonsdk.QtConfigure;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
	QtConfigure.setCustomDomain("your data collection service domain", null);
        // Enable debug logging.
        QtConfigure.setLogEnabled(true);
        QtTrackAgent.enableFragmentPageCollection(true);
        // Enable automatic collection of widget click events.
        QtTrackAgent.setAutoEventEnabled(true);
        //...
    }
    //...
    
}

The following control types support automatic monitoring:

Control

Description

CheckBox

Automatically instruments the onCheckedChanged method to log events.

RadioButton

Automatically instruments the onCheckedChanged method to log events.

ToggleButton

Switch

Button

ImageButton

CheckedTextView

TextView

ImageView

RatingBar

Automatically instruments the onRatingChanged method to log events.

SeekBar

Automatically instruments the onStopTrackingTouch method to log events.

Spinner

ListView

ExpandableListView

RecyclerView

Automatically tracks events only on child controls within RecyclerView items.

TabHost

TabLayout

MenuItem

Dialog

GridView

Layout

Automatically tracks click events on Layout objects and their subclasses.

8.3.2 Set custom attributes for autotracked PVs

Implement the com.umeng.analytics.autotrack.PageAutoTracker interface for a specific Activity or Fragment to set its custom attributes, page name, or source page name.

public interface PageAutoTracker {
    /**
     * Returns the current page name.
     * @return `null` or an empty string if no custom page name is provided.
     */
    String getPageName();

    /**
     * Returns the referrer page name.
     * @return `null` or an empty string if no custom referrer page name is provided.
     */
    String getRefPageName();

    /**
     * Returns custom properties as a map of key-value pairs. Both keys and values must be strings.
     *
     * @return A map of the custom properties, or `null` if none exist.
     */
    Map<String, String> getTrackProperties();
}

Example:

import com.quick.qt.analytics.QtTrackAgent;

/**
 * Assigns a custom page name and custom page properties to FragmentContacts.
 */
public static class FragmentContacts extends Fragment implements PageAutoTracker {
        private final String mPageName = "FragmentContacts";

        static FragmentSimple newInstance(int num) {
            FragmentSimple f = new FragmentSimple();

            // Supply 'num' as an argument.
            Bundle args = new Bundle();
            args.putInt("num", num);
            f.setArguments(args);

            return f;
        }

        /**
         * Creates the fragment's UI, a simple text view that shows its
         * instance number.
         */
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            FrameLayout fl = new FrameLayout(getActivity());
            fl.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.MATCH_PARENT));
            fl.setBackgroundColor(Color.LTGRAY);
            TextView tv = new TextView(getActivity());
            tv.setText("Fragment Contacts");
            tv.setTextColor(Color.BLACK);
            tv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    QtTrackAgent.ignoreView(v); // Disable auto-tracking and data reporting for the TextView control.
                    Toast.makeText(getActivity(), "The TextView was clicked.", Toast.LENGTH_LONG).show();
                }
            });
            fl.addView(tv);
            return fl;
        }

        // Returns the custom page name for FragmentContacts.
        @Override
        public String getPageName() {
            return "FragmentContacts";
        }

    	// Returns null because a custom referring page name is not required.
        @Override
        public String getRefPageName() {
            return null;
        }

    	// Returns the custom page properties for FragmentContacts.
        @Override
        public Map<String, String> getTrackProperties() {
            Map<String, String> properties = new HashMap<>();
            properties.put("fragment_arg1", "fragment_value111");
            properties.put("fragment_arg2", "fragment_value222");
            return properties;
        }
    }

8.3.3 Custom attributes for click events

The setViewProperties() method lets you set custom properties for a specific control. You can define these properties as one or more key-value pairs, where the key and value must both be strings. The autocaptured data for the click event will then include these custom properties.

/**
* Sets custom properties for a control. The properties are a collection of key-value pairs where both the keys and values are strings.
* @param view The control object.
* @param properties The custom properties.
*/
public static void setViewProperties(View view, JSONObject properties);

Example:

import com.quick.qt.analytics.QtTrackAgent;

@QtDataTrackViewOnClick
public void onClick(View v) {
    int id = v.getId();
    Intent in = null;
    if (id == R.id.normal) {
        // Sets the custom event ID to `ekv_normal` for the button widget with the resource ID `normal`.
        // The SDK will then report this widget's click event with the event ID `ekv_normal`.
        QtTrackAgent.setViewEventID(v, "ekv_normal");
        // Sets custom properties for the `normal` button widget's click event (`ekv_normal`).
        // The SDK will then include the properties and values from `customArgs` in the data reported for the `ekv_normal` event.
        JSONObject customArgs = new JSONObject();
        try {
            customArgs.put("customArg1", "value1111");
            customArgs.put("customArg2", "value2222");
        } catch (JSONException e) {
        
        }
        QtTrackAgent.setViewProperties(v, customArgs);
      }
   }

8.3.4 Set custom event codes for control clicks

Use the setViewEventID() method to set a custom event ID for the click event of a specific control.

/**
* Sets a custom event code for the click event of an auto-tracked view.
* @param view The target view.
* @param eventcode The custom event code to set.
*/
public void setViewEventID(View view, String eventcode);

Example:

import com.quick.qt.analytics.QtTrackAgent;

@QtDataTrackViewOnClick
public void onButtonClick(View v) {
    int id = v.getId();
    Intent in = null;
    if (id == R.id.normal) {
       // Assigns the custom event ID `ekv_normal` to the button with the resource ID `normal`.
       // The SDK will now report "ekv_normal" as the event ID when this control is clicked.
       QtTrackAgent.setViewEventID(v, "ekv_normal");
       //...
    }
}

8.3.5 Handle onClick events

A click callback method defined with the android:onClick attribute in a layout file does not automatically trigger the control's click event. To enable the SDK to automatically trigger the event, add the @QtDataTrackViewOnClick annotation to the method specified in the android:onClick attribute. For example:

Layout file:

<Button
    android:id="@+id/normal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="24dp"
    android:onClick="onButtonClick"
    android:text="@string/ana_name"/>

Custom onClick event handler:

import com.quick.qt.analytics.autotrack.QtDataTrackViewOnClick;

@QtDataTrackViewOnClick
public void onButtonClick(View v) {
    //...
}

8.3.6 Ignore automatic click events for specific controls

Use the ignoreViewType() method to disable automatic collection of click events for specific view types.

/**
* Ignores automatic click event collection for a specific view type.
* This method can be called repeatedly to add more view types to the ignore list.
* @param viewType The view type to ignore.
*/
public static void ignoreViewType(Class viewType);

Example:

import com.quick.qt.analytics.QtTrackAgent;

// Ignores click events for Button controls.
QtTrackAgent.ignoreViewType(Button.class);

8.3.7 Ignoring automatic clicks on specific controls

Use the ignoreView() method to exclude a specific control from automatic click event collection.

/**
* Ignores automatic click event collection for the specified View.
*
* @param view The View to ignore.
*/
public static void ignoreView(View view);

Example:

import com.quick.qt.analytics.QtTrackAgent;

Button myButton = (Button)findViewById(R.id.testButton);
// Disable automatic tracking of click events for the myButton view.
QtTrackAgent.ignoreView(myButton);

8.4 Impression tracking

Note

This feature is supported in SDK version 1.8.0 and later. For details, see the Android SDK release notes.

To use auto exposure tracking, you need to manually enable auto exposure in the configuration options.

import com.quick.qt.analytics.QtTrackAgent;

// Enable exposure collection
QtTrackAgent.enableExposureCollection();

You can also disable automatic exposure.

// Disables exposure collection
QtTrackAgent.disableExposureCollection();

8.4.1 Exposure parameters

import com.quick.qt.analytics.exposure.QTExposureConfig;
import com.quick.qt.analytics.QtTrackAgent;

// General exposure settings
QTExposureConfig config = new QTExposureConfig.Builder()
                .setMinDuration(300) // Sets the minimum exposure duration in milliseconds.
                .setMinVisibleRatio(0.5f) // Sets the minimum visible ratio required for an exposure.
                .setRepeated(true) // Enables reporting for repeated exposures.
                .setCallback(new QTExposureConfig.ExposureCallback() { // Sets a callback to be executed when an exposure is detected.
                    @Override
                    public void onExposure(View view) {
                        Toast.makeText(mContext, "Exposure successful", Toast.LENGTH_SHORT).show();
                    }
                })
                .build();
        
QtTrackAgent.setExposureConfig(config);

The QTExposureConfig property specifies the exposure configuration:

Parameter

Type

Description

minVisibleRatio

float

The minimum exposure ratio. The valid range is 0.0f to 1.0f. The default is 0.5f.

  • If set to 0.0f, an exposure tracking event is triggered as soon as any part of the element is visible.

  • If set to 1.0f, an exposure tracking event is triggered only when the entire element is visible.

minDuration

long

The effective exposure duration in milliseconds. An exposure tracking event is triggered only if the element remains visible for longer than this duration. The default is 300.

repeated

boolean

Specifies whether to allow repeated exposure tracking events. The default is true.

  • If set to true, a new exposure tracking event is triggered if the element reappears and meets the exposure conditions.

  • If set to false, the exposure tracking event is triggered only once. It will not be triggered again, even if the element reappears.

callback

QTExposureConfig.ExposureCallback

The callback executed when an exposure tracking event is triggered.

8.4.2 Global exposure settings

To set the global exposure property, call the QtTrackAgent.setExposureConfig(config) method before initializing the SDK.

import com.quick.qt.analytics.exposure.QTExposureConfig;
import com.quick.qt.analytics.QtTrackAgent;

// General exposure settings
QTExposureConfig config = new QTExposureConfig.Builder()
                .setMinDuration(300) // Minimum exposure duration in milliseconds
                .setMinVisibleRatio(0.5f) // Minimum visible ratio
                .setRepeated(true) // Specifies whether to track repeated exposures
                .setCallback(new QTExposureConfig.ExposureCallback() { // Sets the exposure callback
                    @Override
                    public void onExposure(View view) {
                        Toast.makeText(mContext, "Exposure successful", Toast.LENGTH_SHORT).show();
                    }
                })
                .build();
        
QtTrackAgent.setExposureConfig(config);

8.4.3 Mark an exposure element

To use the exposure feature, manually bind an exposure element by calling QtTrackAgent.addExposureView().

import com.quick.qt.analytics.QtTrackAgent;

  /**
   * Marks a view for exposure tracking.
   *
   * @param view The view to track for exposure.
   * @param data The exposure data.
   */
public static void addExposureView(View view, QTExposureData data) {
    QtTrackAgent.addExposureView(view, data);
}

Parameters:

Parameter

Type

Description

view

View

The view object to track for exposure.

data

QTExposureData

The exposure data object (see the table below for details).

QTExposureData API:

// Import package
import com.quick.qt.analytics.exposure.QTExposureData;

/**
 * Constructs a QTExposureData object with the specified event name.
 *
 * @param event The name of the event.
 */
public QTExposureData(String event) 

/**
 * Constructs a QTExposureData object with the specified event name and custom properties.
 *
 * @param event      The name of the event.
 * @param properties A map of custom properties for the event.
 */
public QTExposureData(String event, Map<String, Object> properties) 

/**
 * Constructs a QTExposureData object with the specified event name, custom properties, and exposure configuration.
 *
 * @param event           The name of the event.
 * @param properties      A map of custom properties for the event.
 * @param exposureConfig  The configuration for this exposure.
 */
public QTExposureData(String event,  Map<String, Object>  properties, QTExposureConfig exposureConfig) 

Parameter descriptions:

Parameter

Type

Description

event

String

Event name (required)

properties

Map<String,Object>

Properties for the exposure event (optional)

config

QTExposureConfig

Exposure configuration (optional, defaults to the global configuration)

Note:

  1. property names and String property values can only contain letters, numbers, and underscores.

  2. A property value can be one of the following Java types: String, Long, Integer, Float, Double, or Short.

  3. If a key matches an existing global property key, its value is updated. Otherwise, a new global property is inserted.

    Example:

    import com.quick.qt.analytics.exposure.QTExposureData;
    
    Map<String, Object> properties = new HashMap<>();
    properties.put("param1", item.text); // custom parameter 1
    properties.put("param2", position); // custom parameter 2
    
    QTExposureData exposureData = new QTExposureData("event code", properties))
Standard element tagging

Sample code:

import com.quick.qt.analytics.exposure.QTExposureData;
import com.quick.qt.analytics.QtTrackAgent;

// Construct exposure data.
QTExposureData exposureData = new QTExposureData("exposure_view_click");
QtTrackAgent.addExposureView(imageView, exposureData);
Tagging list elements

Select all elements

import com.quick.qt.analytics.exposure.QTExposureConfig;
import com.quick.qt.analytics.exposure.QTExposureData;
import com.quick.qt.analytics.QtTrackAgent;

// Construct exposure data.
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
    View view = holder.xxxx; 
    Map<String, Object> properties = new HashMap<>();
    // Add custom parameters.
    properties.put("param1", item.text);
    properties.put("param2", position);
    QtTrackAgent.addExposureView(convertView, new QTExposureData(item.text, properties));
}

Tag an element:

Note

Individual items in a list are often reused or change position, for example, during refreshes, deletions, or additions. We recommend that you add the $$item_reused_id field to your exposure data and ensure that the ID is unique.

import com.quick.qt.analytics.exposure.QTExposureConfig;
import com.quick.qt.analytics.exposure.QTExposureData;
import com.quick.qt.analytics.QtTrackAgent;

// Construct the exposure data.
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
     View view = holder.xxxx; 
     if(item.text.contains("New")){
          Map<String, Object> properties = new HashMap<>();
          properties.put("$$item_reused_id","your_unique_item_id"); // Set a unique custom ID to prevent duplicate tracking from view reuse.
          properties.put("text", item.text); // custom parameter 1
          properties.put("position", position); // custom parameter 2
          QtTrackAgent.addExposureView(convertView, new QTExposureData(item.text, properties));
     }
}

8.4.4 Remove an exposed element

Removing an element removes its event tracking (for example, deleting a list).

Alternatively, call QtTrackAgent.removeExposureView() to exclude elements from exposure collection.

import com.quick.qt.analytics.QtTrackAgent;

/**
 * Removes a view from exposure tracking.
 *
 * @param view           The view to remove.
 * @param item_reused_id The custom id assigned to the view.
 */
QtTrackAgent.removeExposureView(view, "your_custom_id");

9 Viral sharing

Viral sharing is a key growth hacking concept where users spread information through their social connections, driving new user acquisition.

After integrating the SDK for viral sharing, you can use the viral sharing trend model and sharing return metrics on the QuickTracking platform to measure the user acquisition effectiveness of your marketing campaigns.

  1. View referral performance metrics for your top sharers across referral levels.

  2. Flexibly configure and combine referral metrics to identify top-performing users based on their viral acquisition capability and referral conversion capability. Track the viral sharing path and referral relationships to pinpoint your key opinion consumers (KOCs).

9.1 Getting referral share parameters

import com.quick.qt.analytics.QtTrackAgent;
/**
 * Retrieves the referral share parameters.
 * @param context The required ApplicationContext object from the host app.
 * */
public static Map<String, String> getRefShareParams(Context context);

Version

Android SDK v1.6.0.PX or later

Feature

Use this API to retrieve the source share ID and source share URL before requesting the share parameters.

Request parameters

Parameter

Type

Default

Description

Notes

context

ApplicationContext

null

The ApplicationContext of the host app.

Required. Cannot be null.

Return Value

Parameter

Type

Default

Description

Remarks

$$_ref_share_url

String

null

The source share URL, excluding the share ID.

Not applicable.

$$_ref_share_id

String

null

The source share ID.

Not applicable.

Request example

import com.quick.qt.analytics.QtTrackAgent;
import com.quick.qt.analytics.share.ShareResultHandler;

public class DemoActivity {
    ...
    public void onShare() {
        Context context = DemoActivity.this;
        Map<String, String> refShareParams = QtTrackAgent.getRefShareParams(context);
        String $$_ref_share_id = refShareParams.get("$$_ref_share_id");
        
        Map<String, String> shareParams = new HashMap<String, String>();
        shareParams.put("shareId", $$_ref_share_id);
        shareParams.put("title", "Share Campaign A");
        shareParams.put("campaign", "Share Campaign A");
        QtTrackAgent.requestShareParams(context, "https://www.taobao.com/productId", shareParams, 0, new ShareResultHandler() {
            @Override
            public void onShareResultSuccess(final JSONObject result) {
                try {
                    Log.i("Test", "shareParams = " + result.toString());
                    String $sid = result.getString("shareId");
                    Map<String, Object> properties = new HashMap<String, Object>();
                    properties.put("$$_share_id", $sid);
                    properties.put("$$_share_url", "https://www.taobao.com/productId"); 
                    properties.put("$$_share_title","Share Campaign A"); 
                    properties.put("$$_share_campaign_id", "This is a custom share campaign");
                      // 
                    properties.put("$$_share_type", "Custom share destination");
                    QtTrackAgent.onEventObject(this, "$$_share", properties);
                    // This operation runs on a background thread.
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            // Perform some background tasks...

                            // To update the UI, switch back to the main thread.
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    // Show the dialog on the main thread.
                                    AlertDialog.Builder builder = new AlertDialog.Builder(context);
                                    builder.setTitle("Share Parameters");
                                    builder.setMessage(result.toString());
                                    builder.show();
                                }
                            });
                        }
                    }).start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onShareResultFail(Throwable t) {
                Log.i("Test", "fail = " + t.getMessage());
            }
        });
    }
    ...
}

9.2 Shared parameters

import com.quick.qt.analytics.QtTrackAgent;
import com.quick.qt.analytics.share.ShareResultHandler;

/**
 * Retrieves the parameters required to generate a share URL.
 * @param context The ApplicationContext of the host app. Must not be null.
 * @param url The URL of the page to share. Must not be null.
 * @param params A map of share parameters. This parameter is optional and can be null.
 *    {
 *      title: The share title. Optional. The maximum length is 4,096 bytes.
 *      campaign: The share campaign. Optional. The maximum length is 4,096 bytes.
 *      shareId: The source share ID. Optional.
 *      ... and other extensible parameters.
 *  }
 * @param timeout The request timeout in seconds. The valid range is 0 to 10, inclusive. If you set this parameter to 0, the SDK uses the default timeout of 3 seconds.
 * @param callback The result callback object. Must not be null.
 */
public static void requestShareParams(Context context, String url, Map<String, String> params, int timeout,final ShareResultHandler callback)

Version

Android SDK v1.6.0.PX or later

Feature

Requests the share ID needed to build a share link.

Parameters

Parameter

Type

Default

Description

Remarks

context

Context

null

The ApplicationContext of the host app.

Required; cannot be null.

url

String

null

The URL of the page to share.

Required; cannot be null.

params

Map<String,String>

null

Request parameters for the share parameter retrieval API.

  • Optional parameters

campaign (String): The share campaign identifier. Max length: 4,096 characters. Default: "".

title (String): The share title. Max length: 4,096 characters. Default: "".

shareId (String): The source share ID. Default: "".

timeout

int

0

API timeout

Timeout in seconds, from 1 to 10. If set to 0, the SDK uses its default timeout of 3 seconds.

callback

ShareResultHandler

null

The result callback object.

Required; cannot be null.

Note: The SDK executes this callback on a background worker thread for network requests. If you need to update UI controls in the callback method, you must post the work to the UI thread using a Handler.

The ShareResultHandler callback interface is defined as follows:

public interface ShareResultHandler {
    // Called when the request for share parameters succeeds.
    void onShareResultSuccess(JSONObject result);
    // Called when the request for share parameters fails. The failure reason is available via t.getMessage().
    void onShareResultFail(Throwable t);
}

Return parameters

Parameter

Type

Default

Description

Notes

data

JSONObject

null

Response from the share parameters API.

Contains the shareId (String) property, which is the ID of the share.

Examples

import com.quick.qt.analytics.QtTrackAgent;
import com.quick.qt.analytics.share.ShareResultHandler;

public class DemoActivity {
    ...
    public void onShare() {
        Context context = DemoActivity.this;
        Map<String, String> shareParams = new HashMap<String, String>();
        shareParams.put("shareId", "");
        shareParams.put("title", "Share Campaign A");
        shareParams.put("campaign", "Share Campaign A");
        QtTrackAgent.requestShareParams(context, "https://www.taobao.com/productId", shareParams, 0, new ShareResultHandler() {
            @Override
            public void onShareResultSuccess(final JSONObject result) {
                try {
                    Log.i("Test", "shareParams = " + result.toString());
                    String $sid = result.getString("shareId");

                    Map<String, Object> properties = new HashMap<String, Object>();
                    properties.put("$$_share_id", $sid);
                    properties.put("$$_share_url", "https://www.taobao.com/productId"); 
                    properties.put("$$_share_title","Share Campaign A"); 
                    properties.put("$$_share_campaign_id", "This is a custom campaign");
                    properties.put("$$_share_type", "user-defined sharing platform");
                    QtTrackAgent.onEventObject(this, "$$_share", properties);
                    
                    // Assume this is an operation in a background thread.
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            // Perform some background tasks...

                            // To update the UI, switch back to the main thread.
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    // Show the dialog on the main thread.
                                    AlertDialog.Builder builder = new AlertDialog.Builder(context);
                                    builder.setTitle("Sharing Parameters");
                                    builder.setMessage(result.toString());
                                    builder.show();
                                }
                            });
                        }
                    }).start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onShareResultFail(Throwable t) {
                Log.i("Test", "fail = " + t.getMessage());
            }
        });
    }
}

9.3 Reporting sharing events

graph TD A[Client reports sharing event] --> B{Business server decides to call API}; B -- No --> C[Process ends]; B -- Yes --> D[Business server calls DataWorks API to report event]; D --> E{DataWorks validates request}; E -- No --> F[DataWorks returns failure]; E -- Yes --> G[DataWorks records event]; G --> H[DataWorks returns success];

Use $$_share to report share events.

Example

import com.quick.qt.analytics.QtTrackAgent;

Map<String, Object> properties = new HashMap<String, Object>();
properties.put("$$_share_id", "share ID obtained from the share parameter API");
properties.put("$$_share_url", "https://www.taobao.com/productId"); 
properties.put("$$_share_title","sharing campaign A"); 
properties.put("$$_share_campaign_id", "My Custom Campaign");
properties.put("$$_share_type", "user-defined sharing platform");
QtTrackAgent.onEventObject(this, "$$_share", properties);

Note: The launch link must include the $sid parameter set to the share ID. For example: https://example.aliyun.com/path/to/content?$sid=123456