Title: Mobile SDK: Android tracking overview and configuration
Author: joshua
Published: August 1, 2022
Last modified: May 21, 2026

---

 1. [Installation resources](https://docs.parse.ly/installation-resources/)
 2. [Add-on Features](https://docs.parse.ly/installation-resources/add-on-features/)
 3. [Mobile app tracking](https://docs.parse.ly/installation-resources/add-on-features/mobile-sdk/)
 4. Mobile SDK: Android tracking overview and configuration

#  Mobile SDK: Android tracking overview and configuration

[[

The Parse.ly Android SDK is a Java library providing Parse.ly tracking functionality
to native Android apps. Like any other framework you might include in your project,
the Parse.ly SDK provides a programming interface usable from your application code.

Github hosts the [official repository](https://github.com/Parsely/parsely-android).

## Including the SDK in a project

To use Parse.ly SDK in your Android project, add the following dependency to your
app’s `build.gradle` file:

    ```lang-shell
      dependencies {
        implementation "com.parsely:parsely:<release_version>”
    }
    ```

To find the newest release version, see the [GitHub Releases](https://github.com/Parsely/parsely-android/releases)
page or [MavenCentral portal](https://central.sonatype.com/artifact/com.parsely/parsely/3.0.7/versions).

## Using the SDK

### Initialization

You must initialize the SDK before using it.
We recommend initializing the SDK as
early as possible in the app lifecycle.

    ```lang-js
    ParselyTracker.init("example.com", /site id/ 30, /flush interval/ this, /context/ false, /dry-run/)
    ```

### Usage

The SDK can be used in two ways, depending on the needs of the consuming app

#### Via a static call

To obtain a reference to the SDK statically, one can use `sharedInstance()` method:

    ```lang-js
    ParselyTracker.sharedInstance().trackPageView("example.com")
    ```

#### Via an interface

It’s possible to use the SDK via an interface, which allows for easier testing and
mocking of the SDK.

    ```lang-js
    fun onCreate(…) {
      ParselyTracker.init(…)
      val tracker = ParselyTracker.sharedInstance()val someClass = SomeClass(tracker) someClass.openArticle()
    }

    class SomeClass(val tracker: ParselyTracker) {
      fun openArticle() {
        tracker.startEngagement()
      }
    }
    ```

**Deprecated**

`4.0.0` no longer supports the following initialization methods.

In any file that uses the Parsely SDK, be sure to add this line at the top of the
file:

    ```lang-js
      import com.parsely.parselyandroid.*;
    ```

Before using the toolkit, you must initialize the Parsely object with your public
siteId. This is usually best to do in the `MainActivity`‘s `onCreate` method.

    ```lang-js
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ParselyTracker.sharedInstance("example.com", this);
      }
    ```

## Providing metadata

We only require pageview metadata for URLs that are not accessible over the internet(
i.e. app-only content) or if you are using an “in-pixel” integration. Otherwise,
Parse.ly’s crawler will gather metadata.

NOTE for the metadata integration types below, it is possible to send a canonical
URL that does not need to resolve to an extant page when navigated to in a browser.
If you do this, it is important that the mobile post’s canonical URL match a domain
that we are tracking for the [Site ID](https://docs.parse.ly/site-id/). The URL 
should also be unique to the post among all posts for the Site ID.

There are two methods for providing Parse.ly with metadata for content that’s only
accessible via the Mobile SDK:

 1. Primary recommendation: updating metadata using the [metadata API endpoint](https://docs.parse.ly/api-metadata-endpoint/).
 2. Back-up option: Sending metadata “in-pixel” with every event sent with the Mobile
    SDK. We only recommend this for special cases. For example, this is an appropriate
    method for a mobile-app only company.

**Note**

You should only use the “in-pixel” method if **all **of the content on your app 
is app-only.

## API Documentation

### ParselyTracker.trackPageview

Register a pageview event using a URL and optional metadata. You should only call
this method once per page view.

| Parameter | Type | Required | Description | 
| url | String | yes | The URL of the tracked article (eg: “[http://example.com/some-old/article.html](http://example.com/some-old/article.html)“) | 
| urlRef | String | no | The url of the page that linked to the viewed page. Analogous to HTTP referrer | 
| urlMetadata | Map<String, Object> | no | Optional metadata for the URL — uncommon. Only needed when `url` isn’t accessible over the Internet (i.e. app-only content). Do not use this for **content also hosted on** URLs Parse.ly would normally crawl. | 
| extraData | Map<String, Object> | no | A Map of additional information to send with the event. | 
| siteIdSource | SiteIdSource | no | The source of the site ID to use for the event. If [SiteIdSource.Default], the site ID provided during [init] will be used. Otherwise, the site ID provided in the [SiteIdSource.Custom] object will be used. |

### ParselyTracker.startEngagement (heartbeat tracking)

Starts engaged time tracking for the given URL.

Start engaged time tracking for the given URL. Once called, the Parse.ly tracking
script will automatically send `heartbeat` events periodically to capture engaged
time for this url until engaged time tracking stops.

This call also automatically stops tracking engaged time for any urls that are not
the current url.

The value of `url` should be a URL for which `trackPageview` has been called.

| Parameter | Type | Required | Description | 
| url | String | yes | The URL of the tracked article (eg: “[http://example.com/some-old/article.html](http://example.com/some-old/article.html)“) | 
| urlRef | String | no | The url of the page that linked to the page being engaged with. Analogous to HTTP referrer | 
| extraData | Map<String, Object> | no | A map of additional information to send with the generated `heartbeat` events |

### ParselyTracker.stopEngagement

Stops the engaged time tracker, sending any accumulated engaged time to Parse.ly.

_NOTE: _This **must** be called during various Android lifecycle events like `onPause`
or `onStop`. Otherwise, engaged time tracking may keep running in the background
and Parse.ly values may be inaccurate.

### ParselyTracker.trackConversion

Track a conversion event (e.g. newsletter signup, subscription, purchase, lead capture).
The SDK constructs a `conversion` event with the goal identity carried in `extraData`
and dispatches it through the same flush queue and `mobileproxy` endpoint used by`
trackPageview` — no separate setup or network plumbing required.

Recommended implementation: Call `trackConversion` at the moment a conversion completes—
after a paywall purchase succeeds, a newsletter signup form is submitted, a lead-
capture form is sent, a paid plan is activated, etc. For best attribution results,
call `trackPageview` for the relevant in-app pages before the conversion so the 
conversions topology has session history to attribute against.

| Parameter | Type | Required | Description | 
| url | String | yes | The url at which the conversion occurred | 
| conversionType | ConversionType | yes | The category of conversion. One of `ConversionType.NEWSLETTER_SIGNUP`, `ConversionType.LEAD_CAPTURE`, `ConversionType.LINK_CLICK`, `ConversionType.SUBSCRIPTION`, `ConversionType.PURCHASE` | 
| conversionLabel | String | yes | A customer-defined identifier for this conversion (e.g. `"Homepage CTA"`, `"Annual Subscription"`). Should be non-empty — events without a meaningful label appear in the conversions report as blank | 
| urlRef | String | No | The url of the page that linked to the conversion page. Analogous to HTTP referrer | 
| urlMetadata | ParselyMetadata | No | Optional metadata for the URL — uncommon. Only needed when `url` isn’t accessible over the Internet (i.e. app-only content). Do not use this for content also hosted on URLs Parse.ly would normally crawl | 
| extraData | Map<String, Object> | no | A Map of additional information to send with the event. The reserved keys `_conversion_type` and `_conversion_label` will be overwritten by the typed parameters above | 
| siteIdSource | SiteIdSource | no | The source of the site ID to use for the event. If `SiteIdSource.Default`, the site ID provided during `init` will be used. Otherwise, the site ID provided in the `SiteIdSource.Custom` object will be used |

### ParselyTracker.trackPlay

Starts video tracking.

This starts tracking view time for a video that someone is watching at a given url.
It will send a `videostart` event unless the same url/parse-ly-video-tracking/Id
had previously been paused. Video metadata must be provided, specifically the video
ID and video duration.
The `url` value is _not_ the URL of a video, but the post
which contains the video. If the video is not embedded in a post, then this should
contain a well-formatted URL on the customer’s domain (e.g. http://example.com/app-
videos). This URL doesn’t need to return a 200 status when crawled, but must but
well-formatted so Parse.ly systems recognize it as belonging to the customer.If 
a video is already being tracked when this method is called, unless it’s the same
video, the existing video tracking will be stopped and a new `videostart` event 
will be sent for the new video.

| Parameter | Type | Required | Description | 
| url | String | yes | URL of post with the embedded video. If you haven’t embedded the video, then send a valid URL matching your domain. (e.g. http://example.com/app-videos) | 
| urlRef | String | no | The url of the page that linked to the page being engaged with. Analogous to HTTP referrer | 
| videoMetadata | Map<String, Object> | yes | Metadata about the tracked video. | 
| extraData | Map<String, Object> | no | A Map of additional information to send with the event. |

### ParselyTracker.trackPause

Pause video tracking for an ongoing video. If [trackPlay] is immediately called 
again for the same video, a new `videostart` event will not be sent. This models
a user pausing a playing video.

NOTE: This or [resetVideo] **must** be called during various Android lifecycle events
like `onPause` or `onStop`. Otherwise, engaged time tracking may keep running in
the background and Parse.ly values may be inaccurate.

### ParselyTracker.resetVideo

Stops video tracking and resets internal state for the video. If [trackPlay] is 
immediately called for the same video, a new `videostart` event is set. This models
a user stopping a video and (on [trackPlay] being called again) starting it over.

NOTE: This or [trackPause] **must** be called during various Android lifecycle events
like `onPause` or `onStop`. Otherwise, engaged time tracking may keep running in
the background and Parse.ly values may be inaccurate.

### ParselyTracker.flushEventQueue

**Deprecated**

Android SDK (3.1.1) deprecates this function.

Empties the event queue and sends the appropriate requests to Parsely. Called automatically
after a number of seconds determined by `flushInterval`.

To make sure all of the queued events are flushed to Parse.ly’s servers, include
a call to `flushEventQueue()` in your main activity’s `onDestroy()` method.

### ParselyMetadata

Represents post metadata to be passed to Parsely tracking.

This class is used to attach a metadata block to a Parse.ly pageview request. Pageview
metadata is only required for URLs not accessible over the internet (i.e. app-only
content) or if the customer is using an “in-pixel” integration. Otherwise, metadata
will be gathered by Parse.ly’s crawling infrastructure.

**Changes from v3.x to 4.x**

`authors` and `tags` were of type `ArrayList` but are now `List<String>`

| Parameter | Type | Required | Description | 
| authors | List<String> | no | The names of the authors of the content. We accept up to 10 authors. | 
| link | String | no | A post’s [Parse.ly canonical URL](https://docs.parse.ly/the-parsely-canonical-url/). | 
| section | String | no | The category or vertical to which this content belongs. | 
| tags | List<String> | no | User-defined tags for the content. We support up to 20. | 
| thumbUrl | String | no | URL where you’re hosting the main image for this content. | 
| title | String | no | The title of the content. | 
| pubDate | Calendar | no | The publication date for this content. |

### ParselyVideoMetadata

This class is an implementation of `ParselyMetadata` for videos.

**Changes from v3.x to 4.x**

`authors` and `tags` were of type `ArrayList` but are now `List<String>`

| Parameter | Type | Required | Description | 
| authors | List<String> | no | The names of the authors of the video. We support up to 10 authors. | 
| videoId | String | yes | Unique identifier for the video. Functions similarly to the [Parse.ly Canonical URL](https://docs.parse.ly/the-parsely-canonical-url/) that Posts use.
It appears as the `"link"` value in the [video network call’s](https://docs.parse.ly/test-integration/#h-review-the-videostart) metadata. Additionally, this value should match the `“link”` passed for the video in the web channel. | 
| section | String | no | The category or vertical to which this video belongs. | 
| tags | List<String> | no | User-defined tags for the video. We permit up to 20. | 
| thumbUrl | String | no | URL at which the main image for this video is located. | 
| title | String | no | The title of the video. | 
| pubDate | Calendar | no | The publication date for this video in milliseconds. | 
| durationSeconds | int | yes | Duration of the video in seconds. |

## Configuring Audience Segments

If your contract includes [Audience Segments](https://docs.parse.ly/installation-developer-resources/add-on-features/setting-up-audience-segments-parsely/),
you can use the extraData parameter in the [page view](https://docs.parse.ly/installation-resources/add-on-features/mobile-sdk/android-sdk?output_format=md#trackpageview)
and [engagement](https://docs.parse.ly/installation-resources/add-on-features/mobile-sdk/android-sdk?output_format=md#startengagement)
events.

Pass extraData to set the desired audience(s) in the format of `extraData: ["key":"
value"]`. For example:

    ```lang-js
    Subscribers: extra_data['subscriber'] == 'true'
    Non-subscribers: extra_data['subscriber'] == 'false' 
    ```

To see the full context, review the [sample code on GitHub](https://github.com/Parsely/parsely-android/blob/main/example/src/main/java/com/example/MainActivity.java#L102-L111).

Last updated: May 21, 2026