Integration with Android

Android is the most used mobile platform in the world. We are very happy to having an official integration library for Android. If you are looking for React Native please check React Native for iOS please check iOS docs. For other mobile integrations please check mobile integration. If you are with Android, you are in the right place. Let's start!

Installation

Installation with Gradle

Step 1. Add the JitPack repository to your build file

Add `maven { url 'https://jitpack.io' }` it in your root build.gradle at the end of repositories:

gradle

        dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
            mavenCentral()
            maven { url 'https://jitpack.io' }
          }
        }
        

Step 2. Add the dependency to your app dependencies:

gradle

        dependencies {
	        implementation 'com.github.metricalp:android:1.5'
	}
        

Installation with Maven

Step 1. Add the JitPack repository to your build file

gradle

      <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
      </repositories>
        

Step 2. Add the dependency to your app dependencies:

gradle

    <dependency>
        <groupId>com.github.metricalp</groupId>
        <artifactId>android</artifactId>
        <version>1.5</version>
    </dependency>
        

Usage

We tried to make integration flexible and smooth to keep developer experience in best level. Here we will share a complete MainActivity.kt example to show how you can integrate Metricalp to your Android app. We will describe the code step by step as detailed below.

kotlin
package com.myapp.test

import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.metricalp.android.Metricalp
import com.myapp.test.ui.theme.TestappTheme
import java.util.UUID

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val sharedPref = getSharedPreferences("app_data", Context.MODE_PRIVATE)
        var uuid = sharedPref.getString("user_uuid", null);
        if (uuid == null) {
            uuid = UUID.randomUUID().toString()
            with (sharedPref.edit()) {
                putString("user_uuid", uuid)
                apply()
            }
        }
        Metricalp.init(hashMapOf<String, String?>("tid" to "mam48", "metr_unique_identifier" to uuid,  "app" to "ExampleApp@1.0.0", "metr_user_language" to "English-US"), null, null)
        setContent {
            TestappTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    RenderButton()
                }
            }
        }
    }

    public override fun onStart() {
        super.onStart()
        Metricalp.screenViewEvent("MainScreen", null, null);
    }

    public override fun onStop() {
        super.onStop()
        Metricalp.appLeaveEvent(null, null);
    }
}

@Composable
fun RenderButton() {
    Button(onClick = { Metricalp.customEvent("button_click", hashMapOf<String, String>("path" to "HomepageScreen", "custom_prop1" to "top_button", "theme" to "dark"), null ) }) { Text("Button") }
}

We know it is a very ugly app but it will help to get it fundamentals, trust us. Firstly, we imported import com.metricalp.android.Metricalp library which we call methods through it.

The first method to call is Metricalp.init and the most important one is to properly integrate. We will init Metricalp to collect events. It is important to do this in entrypoint file (MainActivity). Metricalp.init takes attributes (HashMap<String,String>), initial screen path (for auto triggered first screen_view as optional). If provide initial screen as null, then it will skip auto triggered first screen_view event. We can also pass event attributes for that first screen view event, as optional another argument again. Otherwise just pass null. Let's explain:

Metricalp.init() Attributes Argument Props

app

You should provide your app name and version. It is important to provide version to track it in dashboard. You can provide it as AppName@Version syntax ExampleApp@1.0.0 like above example.

metr_user_language

You should provide your current app language. You can provide it as Language (long name)-Country(ISO Code) syntax English-US like above example or Spanish-ES orTurkish-TR etc. If you are not sure about country, you can provide unknown. For example English-unknown

metr_unique_identifier (required)

We need to explain this metr_unique_identifier prop. Normally in Web tracking, while Metricalp is not using cookies as we mentioned in many places, we are identifying users with their IP addresses in one-way hashes. The formula is something like this: hash(user_ip + user_agent + salt). Here ip + user_agent is almost unique for every user. But in mobile apps, user agent strings are inconsistent and not reliable. So we need to have a unique identifier for every user. We left this unique identifier to you. You can use any unique identifier for your app. For example if it is an authorization app and you are tracking only after users logged-in, then you can provide user ids. Or you can use device related real unique identifiers (Android and iOS has some native methods to get it). Or, you can generate a random UUID when user first opens the app and store it in local storage. Then use it as metr_unique_identifier. Now, the hashing algorithm will be like hash(user_ip + metr_unique_identifier + salt). In this approach, the metr_unique_identifier will be unchanged unless user removes and re-installs the app. But that is fair enough. If it is not enough for you, you can provide your own unique identifier as we mentioned above. User ID or device identifier or any other combination.

In the above example we generated random UUID, put it to sharedPreferences (permanent storage) and used it as metr_unique_identifier. We are suggesting to use this approach. But you can use any unique identifier for your app. But keep in mind, it should be unique for every user and should not change unless user removes and re-installs app.

metr_bypass_ip

This is an optional prop. Possible values are "enable" or "disable". If you see above final hash example with metr_unique_identifier: hash(user_ip + metr_unique_identifier + salt), we still have IP info in the hash. Then, when user for example in Wifi and then changed to mobile network, then IP will be changed. While metr_unique_identifier is same, because of IP change, it may count as another unique count for that day. This setting removes also ip from hash. If you set this as "enable", then we will not use IP in hash function (as default): hash(metr_unique_identifier + salt). But if you pass disable, then ip will also used in hash function: hash(user_ip + metr_unique_identifier + salt). We are not suggesting this because breaking unique count with ip is meaningless in most scenarios for mobile. Then, we set this settings default as enable. So, in most scenarios just do not pass this option, let it be default (enable).

tid (required)

You should provide your TID (a.k.a Tracking ID) to init method. You can get it from Metricalp dashboard. It is required. If you don't provide it, you will get an error. You can find your tid in Embed & Share Tracker page.

There is one important system event in Metricalp screen_view. We are tracking visited screens, bounce rates etc based on this event. So, we strongly suggesting that you should trigger this event in your app additional to any custom events. In your navigation logic, on every screen change by user you should trigger a screen_view event. In above example, we are listening onStart by Android and triggering this event. You can trigger it in somewhere else, place is not important but we are advising that you should trigger this event in somewhere for better tracking.

kotlin
      ...
      ...
      public override fun onStart() {
          super.onStart()
          Metricalp.screenViewEvent("MainScreen", null, null);
      }
  
      ...
      ...

Metricalp.screenViewEvent method provided by library to make it easier for you. You should provide current screen name (path) to this method. You can also pass any additional data (custom props) to this method as second argument (again HashMap<String,String>). The third argument is another HashMap if you wish override initial props (settings) for current event otherwise just pass null.

kotlin
Metricalp.screenViewEvent("MainScreen", hashMapOf<String, String>("custom_prop1" to "Unauthenticated User"), null);

or

kotlin
Metricalp.screenViewEvent("MainScreen", hashMapOf<String, String>("theme" to "Dark Theme"), null);

Here the theme is a custom prop alias. You can check Custom Event & Props docs for detailed info.

Basically that is all. You successfully integrated your Android app with Metricalp now. One more thing is, you can also create some custom events to get more deep insights.

There is another important thing is generating necessary leave events on application leave. Metricalp also provides a custom method for this Metricalp.appLeaveEvent(). You can see that we are triggering this appLeave event in onStop handler. This helps us to catch screen view durations of users. You can also pass any additional data (custom props) to this method as first argument (again HashMap<String,String>). The second argument is another HashMap if you wish override initial props (settings) for current event otherwise just pass null.

kotlin
 public override fun onStop() {
        super.onStop()
        Metricalp.appLeaveEvent(null, null);
    }

Custom Events

There is also another method from library for custom events: Metricalp.customEvent. It takes event type as first argument and data attributes as second argument. The third argument is another HashMap if you wish override initial props (settings) for current event otherwise just pass null. You can use it like:

kotlin
Metricalp.customEvent("button_click", hashMapOf<String, String>("path" to "HomepageScreen", "custom_prop1" to "top_button", "theme" to "dark"), null )

Here we passed path info, also we passed top_button info as custom_prop. We passed another custom prop theme but we used alias this time. You can check Custom Event & Props for detailed info. Now with power of custom events and props you can track and analyze any event to get deep insights in your Android app easily.