Countly Documentation

Countly Resources

Here you'll find comprehensive guides to help you start working with Countly as quickly as possible.

Android SDK

This document will guide you through the process of Countly SDK installation.

Minimum Android version

Countly Android SDK needs a minimum of Android 2.3+ (API Level 9).

Adding Countly SDK

You can use both Android Studio and Eclipse to add Countly SDK to your project.

Adding via Android Studio

To download the SDK package you can use the default JCenter repository. If it's not included in your project, include it like this:

buildscript {
    repositories {
        jcenter()
    }
}

You can also add the Bintray Maven repository:

buildscript {
    repositories {
        maven {
            url  "http://dl.bintray.com/countly/maven"
        }
    }
}

Now, add Countly SDK dependency (use latest SDK version below).

dependencies {
		compile 'ly.count.android:sdk:17.09'
}

Adding SDK via Eclipse

Eclipse users can download JARs - sdk.jar or sdk.jar & sdk-messaging.jar depending on whether you need Countly Push support or not from Github Releases page.

Another option for Eclipse users is to use sources instead of jars. To do that, just create 2 or 3 packages and put sources from Github repository into corresponding packages.

Generate personalized SDK code snippets

Countly Code Generator can be used to generate SDK custom code snippets easily and fast. You can provide values for your custom event, or user profile, or just start with basic integration and this service will generate necessary code for you to use in your favorite IDE (e.g Android Studio).

Component
Package name
Path at Github repo

Countly SDK

ly.count.android.sdk

countly-sdk-android/sdk/src/main/java/ly/count/android/sdk

OpenUDID

org.openudid

countly-sdk-android/sdk/src/main/java/org/openudid

Countly Push SDK

ly.count.android.sdk.messaging

countly-sdk-android/sdk/src/main/java/ly/count/android/sdk/messaging

Setting up Countly SDK

First, you'll need to decide which device ID generation strategy to use. There are several options defined below:

First and easiest method is, if you want Countly SDK to take care of device ID seamlessly, use line below. Do not put a trailing "/" at the end of the server URL or it won't work. Starting from the version 16.12.03, the SDK will erase the trailing "/" and write a warning to the log.

Countly.sharedInstance().init(this, "https://YOUR_SERVER", "YOUR_APP_KEY")

Which server/host should I use inside SDK?

If you are using Countly trial server (try.count.ly), host should be set to https://try.count.ly.

If you use Community Edition and Enterprise Edition, use your own domain name.

Second, you can specify device ID by yourself if you have one (it has to be unique per device):

Countly.sharedInstance().init(this, "https://YOUR_SERVER", "YOUR_APP_KEY", "YOUR_DEVICE_ID")

Third, you can rely on Google Advertising ID for device ID generation.

Countly.sharedInstance().init(this, "https://YOUR_SERVER", "YOUR_APP_KEY", null, DeviceId.Type.ADVERTISING_ID)

Or, you can use OpenUDID:

Countly.sharedInstance().init(this, "https://YOUR_SERVER", "YOUR_APP_KEY", null, DeviceId.Type.OPEN_UDID)

For all of those different approaches, Countly.sharedInstance().init(...) method should be called from your Application subclass (preferred), or from your main activity onCreate method.

In the case of OpenUDID you'll need to include following declaration into your AndroidManifest.xml:

<service android:name="org.openudid.OpenUDID_service">
    <intent-filter>
        <action android:name="org.openudid.GETUDID" />
    </intent-filter>
</service>

In the case of Google Advertising ID, please make sure that you have Google Play services 4.0+ included into your project. Also note that Advertising ID silently falls back to OpenUDID in case it failed to get Advertising ID when Google Play services are not available on a device.

After Countly.sharedInstance().init(...) call you'll need to add following calls to all your activities:

  • Call Countly.sharedInstance().onStart() in onStart.
  • Call Countly.sharedInstance().onStop() in onStop.

Additionally, make sure that INTERNET permission is set if there's none in your manifest file.

Changing a device ID

In case your application authenticates users, you can also change device ID to your user ID later. This helps you identify a specific user with a specific ID on a device she logs in, and the same scenario can also be used in cases this user logs in using a different way (e.g tablet, another mobile phone or web). In this case any data stored in Countly server database and associated with temporary device ID will be transferred into user profile with device id you specified in the following method call:

Countly.sharedInstance().changeDeviceId("new device ID")

Whenever your authenticated user logs out, in case you want to track history and further activity under another Countly user, call:

Countly.sharedInstance().changeDeviceId(DeviceId.Type.OPEN_UDID, null)

You can also set Advertising ID as your device ID generation strategy or even supply your own string with DeviceId.Type.DEVELOPER_SPECIFIED type.

Retrieving the device id and it's type
You may wanty to see what device id Countly is assigning for the specific device and what the source of that id is. For that you may use the following calls. The id type is an enum with the possible values of: "DEVELOPER_SUPPLIED", "OPEN_UDID", "ADVERTISING_ID".

String usedId = Countly.sharedInstance().getDeviceID();
Type idType = Countly.sharedInstance().getDeviceIDType();

Optional parameters during initialization
You can provide optional parameters that will be used during begin_session request. They must be set right after the init function so that they are set before the request is sent to the server. To set them, use the setOptionalParametersForInitialization function. If you want to set those optional parameters, this function has to be called every time the app starts. If you don't to set one off those values, leave that field null.

The optional parameters are:

  • Country code: ISO Country code for the user's country
  • City: Name of the user's city
  • Location: Comma separate latitude and longitude values, for example "56.42345,123.45325"
//the init call before the parameters
Countly.sharedInstance().init(this, "https://YOUR_SERVER", "YOUR_APP_KEY", "YOUR_DEVICE_ID")

//setting optional parameters
Countly.sharedInstance().setOptionalParametersForInitialization("2 character country code", "city", "56.42345,123.45325");

Forcing HTTP POST

If the data sent to the server is short enough, the sdk will use HTTP GET requests. In case you want an override so that HTTP POST is used in all cases, call the "setHttpPostForced" function after you called "init". You can use the same function to later in the apps life cycle disable the override. This function has to be called every time the app starts.

//the init call before the override
Countly.sharedInstance().init(this, "https://YOUR_SERVER", "YOUR_APP_KEY", "YOUR_DEVICE_ID")
  
//enabling the override
Countly.sharedInstance().setHttpPostForced(true);
  
//disabling the override
Countly.sharedInstance().setHttpPostForced(false);

Parameter Tampering Protection

You can set optional salt to be used for calculating checksum of request data, which will be sent with each request using &checksum field. You need to set exactly the same salt on Countly server. If salt on Countly server is set, all requests would be checked for validity of &checksum field before being processed.

Countly.sharedInstance().enableParameterTamperingProtection("salt");

Using Proguard

Proguard obfuscates OpenUDID & Countly Messaging classes. So if you use OpenUDID or Countly Messaging in your application, you need to add following lines to your Proguard rules file:

-keep class org.openudid.** { *; }
-keep class ly.count.android.sdk.** { *; }

Note: Make sure you use App Key (found under Management -> Applications) and not API Key. Entering API Key will not work.

Setting up custom events

A custom event is any type of action that you can send to a Countly instance, e.g purchase, settings changed, view enabled and so. This way it's possible to get much more information from your application compared to what is sent from Android SDK to Countly instance by default.

Data passed should be in UTF-8

All data passed to Countly server via SDK or API should be in UTF-8.

As an example, we will be recording a purchase event. Here is a quick summary what information each usage will provide us:

  • Usage 1: how many times purchase event occured.
  • Usage 2: how many times purchase event occured + the total amount of those purchases.
  • Usage 3: how many times purchase event occured + which countries and application versions those purchases were made from.
  • Usage 4: how many times purchase event occured + the total amount both of which are also available segmented into countries and application versions.
  • Usage 5: how many times purchase event occured + the total amount both of which are also available segmented into countries and application versions + the total duration of those events.

1. Event key and count

Countly.sharedInstance().recordEvent("purchase", 1);

2. Event key, count and sum

Countly.sharedInstance().recordEvent("purchase", 1, 0.99);

3. Event key and count with segmentation(s)

HashMap<String, String> segmentation = new HashMap<String, String>();
segmentation.put("country", "Germany");
segmentation.put("app_version", "1.0");

Countly.sharedInstance().recordEvent("purchase", segmentation, 1);

4. Event key, count and sum with segmentation(s)

HashMap<String, String> segmentation = new HashMap<String, String>();
segmentation.put("country", "Germany");
segmentation.put("app_version", "1.0");

Countly.sharedInstance().recordEvent("purchase", segmentation, 1, 0.99);

5. Event key, count, sum and duration with segmentation(s)

HashMap<String, String> segmentation = new HashMap<String, String>();
segmentation.put("country", "Germany");
segmentation.put("app_version", "1.0");

Countly.sharedInstance().recordEvent("purchase", segmentation, 1, 0.99, 60);

Those are only a few examples with what you can do with custom events. You can extend those examples and use country, app_version, game_level, time_of_day and any other segmentation that will provide you valuable insights.

Timed events

It's possible to create to create timed events by defining a start and stop moment.

String eventName = "Custom event";

//start some event
Countly.sharedInstance().startEvent(eventName);
//wait some time

//end the event 
Countly.sharedInstance().endEvent(eventName);

When ending a event you can also provide additional information. But in that case you have to provide segmentation, count and sum. The default values for those are "null", 1 and 0.

String eventName = "Custom event";

//start some event
Countly.sharedInstance().startEvent(eventName);
//wait some time

Map<String, String> segmentation = new HashMap<>();
segmentation.put("wall", "orange");

//end the event while also providing segmentation information, count and sum
Countly.sharedInstance().endEvent(eventName, segmentation, 4, 34);

Attribution analytics & install campaigns

Countly Attribution Analytics allows you to measure your marketing campaign performance by attributing installs from specific campaigns. This feature is available for Enterprise Edition.

In order to get more precise attribution on Android it is highly recommended to allow Countly to listen to INSTALL_REFERRER intent and you can do that by adding following XML code to your AndroidManifest.xml file, inside application tag.

<receiver android:name="ly.count.android.sdk.ReferrerReceiver" android:exported="true">
	<intent-filter>
		<action android:name="com.android.vending.INSTALL_REFERRER" />
	</intent-filter>
</receiver>

Note that modifying AndroidManifest.xml file is the only thing you would need to do, in order to start getting data from your campaigns via Attribution Analytics plugin.

For more information about how to setup your campaigns, please see this documentation.

Getting user feedback

Star rating integration provides a dialog for getting user's feedback about the application. It contains a title, simple message explaining what it is for, a 1-to-5 star meter for getting users rating and a dismiss button in case the user does not want to give a rating.

This star-rating has nothing to do with Google Play Store ratings and reviews. It is just for getting a brief feedback from users, to be displayed on the Countly dashboard. If the user dismisses star rating dialog without giving a rating, the event will not be recorded.

Star-rating dialog's title, message and dismiss button text can be customized either through the init function or the SetStarRatingDialogTexts function. If you don't want to override one of those values, set it to "null".

//set it through the init function
Countly.sharedInstance().init(context, serverURL, appKey, deviceID, idMode, starRatingLimit, starRatingCallback, "Custom title", "Custom message", "Custom dismiss button text");

//Use the designated function:
Countly.sharedInstance().setStarRatingDialogTexts(context, "Custom title", "Custom message", "Custom dismiss button text");

Star rating dialog can be displayed in 2 ways:

  • Manually, by developer
  • Automatically, depending on session count

In order to display the Star rating dialog manually, you must call the ShowStarRating function. Optionally, you can provide the callback functions. There is no limit on how many times star-rating dialog can be displayed manually.

//show the star rating without a callback
Countly.sharedInstance().showStarRating(context, null);

//show the star rating with a callback
Countly.sharedInstance().showStarRating(context, callback)

Star rating dialog will be displayed automatically when application's session count reaches the specified limit, once for each new version of the application. This session count limit can be specified on initial configuration or through the SetAutomaticStarRatingSessionLimit function. The default limit is 3. Once star rating dialog is displayed automatically, it will not be displayed again unless there is a new app version.

//set the rating limit through the init function
int starRatingLimit = 5;
Countly.sharedInstance().init(context, serverURL, appKey, deviceID, idMode, starRatingLimit, starRatingCallback, starRatingTextTitle, starRatingTextMessage, starRatingTextDismiss);

//set it through the designated function
Countly.sharedInstance().starRatingLimit(context, 5);

If you want to enable the automatic star rating functionality, use SetIfStarRatingShownAutomatically function. It is disabled by default.

//enable automatic star rating
Countly.sharedInstance().setIfStarRatingShownAutomatically(true);

//disable automatic star rating
Countly.sharedInstance().setIfStarRatingShownAutomatically(false);

If you want to have the star rating shown only once per app's lifetime and not for each new version, use the "SetStarRatingDisableAskingForEachAppVersion" function.

//disable star rating for each new version
Countly.sharedInstance().setStarRatingDisableAskingForEachAppVersion(true);

//enable star rating for each new version
Countly.sharedInstance().setStarRatingDisableAskingForEachAppVersion(false);

The star rating callback provides functions for two events. OnRate is called when the user chooses a rating. OnDismiss is called when the user clicks the back button, clicks outside the dialog or clicks the "Dismiss" button. The callback provided in the init function is used only when showing the automatic star rating. For the manual star rating only the provided callback will be used.

CountlyStarRating.RatingCallback callback = new CountlyStarRating.RatingCallback() {
    @Override
    public void OnRate(int rating) {
    	//the user rated the app
    }

    @Override
    public void OnDismiss() {
    	//the star rating dialog was dismissed
    }
};

Setting up User Profiles

Available with Enterprise Edition, User Profiles is a tool which helps you identify users, their devices, event timeline and application crash information. User Profiles can contain any information that either you collect, or is collected automatically by Countly SDK.

You can send user related information to Countly and let Countly dashboard show and segment this data. You may also send a notification to a group of users. For more information about User Profiles, see this documentation.

To provide information about the current user, you must call the Countly.userData.setUserData function. You can call it by providing a bundle of only the predefined fields or call it while also providing a second bundle of fields with your custom keys. After you have provided user profile information, you must save it by calling Countly.userData.save().

//Update the user profile using only predefined fields
Map<String, String> predefinedFields = new HashMap<>();
Countly.userData.setUserData(predefinedFields);
Countly.userData.save()


//Update the user profile using predefined and custom fields
Map<String, String> predefinedFields = new HashMap<>();
Map<String, String> customFields = new HashMap<>();
Countly.userData.setUserData(predefinedFields, customFields);
Countly.userData.save()

The keys for predefined user data fields are as follows:

Key
Type
Description

name

String

User's full name

username

String

User's nickname

email

String

User's email address

organization

String

User's organisation name

phone

String

User's phone number

picture

String

URL to avatar or profile picture of the user

picturePath

String

Local path to user's avatar or profile picture

gender

String

User's gender as M for male and F for female

byear

String

User's year of birth as integer

Using "" for strings or a negative number for 'byear' will effectively delete that property.

For custom user properties you may use any key values to be stored and displayed on your Countly backend. Note: keys with . or $ symbols will have those symbols removed.

Modifying custom data

Additionally you can do different manipulations on your custom data values, like increment current value on server or store a array of values under the same property.

Below is the list of available methods:

//set one custom properties
Countly.userData.setProperty("test", "test");
//increment used value by 1
Countly.userData.increment("used");
//increment used value by provided value
Countly.userData.incrementBy("used", 2);
//multiply value by provided value
Countly.userData.multiply("used", 3);
//save maximal value
Countly.userData.saveMax("highscore", 300);
//save minimal value
Countly.userData.saveMin("best_time",60);
//set value if it does not exist
Countly.userData.setOnce("tag", "test");
//insert value to array of unique values
Countly.userData.pushUniqueValue("type", "morning");
//insert value to array which can have duplocates
Countly.userData.pushValue("type", "morning");
//remove value from array
Countly.userData.pullValue("type", "morning");

//send provided values to server
Countly.userData.save();

In the end always call Countly.userData.save() to send them to the server.

Setting up push notifications

Setting up push notifications involves a few steps that should be completed on Google Developers Console & Firebase Console, your application and Countly dashboard.

With introduction of Firebase, Google deprecated GCM in favour of Firebase Cloud Messaging. Current Countly Android SDK 17.09 will always use GCM. All subsequent versions will use Firebase instead.

In order to use GCM with projects created before Firebase release, please read section Legacy GCM integration below. For new projects (or if legacy integration GCM key doesn't work), please follow these steps:

1. Create new Firebase project (or migrate old Google project to Firebase).
2. Go to Project settings.

3. Select Cloud Messaging tab.

Legacy server key is the key you'll need to copy and paste into Countly Dashboard. Sender ID is number you initialise Countly SDK with.

Legacy GCM integration

In order to set up push notifications, you first have to register your application in Google Developers Console, and then find your Project Number as shown below. Note that this is different from the Project ID.

Then, enable GCM (Google Cloud Messaging) service for your application:

As the final step, get a server token from Credentials menu of APIs & auth section:

Make sure you don't enter any IP address restrictions or make sure those restrictions you've entered play nice with your Countly server.

Setting up the application in Countly dashboard

Open up Countly dashboard, go to Management > Applications section for the application you need and enter Google API token in the GCM Credential section. Then click Validate and then save the changes.

Countly will check the credentials and show error in case you did something wrong.

Integrating push notifications into Android application

Counly SDK for Android largely mimics behavior of our iOS SDK. For example, when your application receives a push notification with a message and your application is in the background, a notification is displayed. If the application is in the foreground, a dialog is displayed.

Read this important notice before push notifications integration

In order to use push notifications for Android, you'll need to include a different version of SDK into your project. We have 2 library projects in Maven, Jcenter and Github: sdk & sdk-messaging. If you want messaging support, include second one (it also adds a dependency on "play-services-gcm"). If you don't, go with the first one.

Add extra lines in AndroidManifest.xml

Make sure your application requests these permissions (replace ly.count.android.demo.messaging with your app package) in the apps manifest file, as shown below:

<permission android:name="ly.count.android.demo.messaging.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="ly.count.android.demo.messaging.permission.C2D_MESSAGE" />

Note that we use Advertising ID for device ID generation purposes in this example. If you want OpenUDID or have your own unique device ID, refer to http://github.com/Countly/countly-sdk-android documentation for details.

And then, change the way you init Countly by adding an additional call to initMessaging:

Countly.sharedInstance()
    .init(this, "YOUR_SERVER", "APP_KEY", null, DeviceId.Type.ADVERTISING_ID)
    .initMessaging(this, YourActivity.class, "PROJECT_NUMBER", Countly.CountlyMessagingMode.TEST);

Here, starting with line .initMessaging, first parameter is an activity which would be started when user clicks on notification, second parameter is its class, and PROJECT_NUMBER is Project Number retrieved from your Google Developers Console. Last parameter controls whether this device is recorded as a test device on Countly server, or as a production device. This would allow you to send messages either to test (using .TEST), or to production (using .PRODUCTION) users only, so you could separate user bases in order to make initial tests.

Behind the scenes, Countly will add latest Google Play Services dependency and add some configuration options to your AndroidManifest.xml during manifest merging by gradle. See sdk-messaging's build.gradle and AndroidManifest.xml for details.

If you want to get notified whenever new message arrives (optional step), register your BroadcastReceiver like this:

@Override
protected void onResume() {
    super.onResume();

    /** Register for broadcast action if you need to be notified when Countly message received */
    messageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Message message = intent.getParcelableExtra(CountlyMessaging.BROADCAST_RECEIVER_ACTION_MESSAGE);
            Log.i("CountlyActivity", "Got a message with data: " + message.getData());
        }
    };
    IntentFilter filter = new IntentFilter();
    filter.addAction(CountlyMessaging.getBroadcastAction(getApplicationContext()));
    registerReceiver(messageReceiver, filter);
}

@Override
protected void onPause() {
    super.onPause();

    /** Don't forget to unregister receiver */
    unregisterReceiver(messageReceiver);
}

Automatic message handling

Countly handles most common message handling tasks for you. For example, it generates and shows Notifications or Dialogs and tracks conversion rates automatically. In most cases you don't need to know how it works, but if you want to customize the behavior or exchange it with your own implementation, here is a more in depth explanation of what it does:

First the received notification payload is analyzed and if it's a Countly notification (has "c" dictionary in payload), processes it. Otherwise, or if the notification analysis says that is a Data-only notification (you're responsible for message processing), it does nothing.

After that it automatically makes callbacks to Countly Messaging server to calculate number of push notifications open and number of notifications with positive reactions.

Here are explanations of common usage scenarios that are handled automatically:

  • Doesn't do anything except for conversions tracking if you specify that it is a Data-only notification in the dashboard. This effectively sets a special flag in message payload so you could process it on your own.
  • It displays a Notification whenever a message arrives and your application is in background.
  • It displays a Dialog when a new message arrives and your application is in foreground.
  • It displays a Dialog when a new message with a action arrives (open URL), and user responds to it by swiping or tapping notification.

A Dialog always has a message, but the buttons set displayed depends on the message type:

  • For notifications without any actions (just a text message) it displays a single Cancel button.
  • For notifications with a URL (you ask user to open a link to some blog post, for instance) it displays Cancel & Open buttons.
  • For notifications with custom buttons it displays corresponding buttons.

Developer-overridden message handling

You can also completely disable push notification handling made by Countly SDK. To do that just add true to the end of your initMessaging() call:

Countly.sharedInstance()
    .init(this, "YOUR_SERVER", "APP_KEY", null, DeviceId.Type.ADVERTISING_ID)
    .initMessaging(this, CountlyActivity.class, "PROJECT_NUMBER", Countly.CountlyMessagingMode.TEST, true);

This parameter effectively disables any UI interactions and Activity instantiation from Countly SDK. To enable custom processing of push notifications you can either register your own WakefulBroadcastReceiver, or use our example with broadcast action. Once you switched off default push notification UI, please make sure to call CountlyMessaging.recordMessageOpen(id) whenever push notification is delivered to your device and CountlyMessaging.recordMessageAction(id, index) whenever user positively reacted on your notification. id is a message id string you can get from c.i key of push notification payload. index is optional and used to identify type of action: 0 for tap on notification in drawer, 1 for first button of rich push, 2 for second one.

Setting up crash reporting

Countly SDK for Android has an ability to collect crash reports which you can examine and resolve later on the server.

Enabling crash reporting

Following function enables crash reporting, that will automatically catch uncaught Java exceptions.

Countly.sharedInstance().enableCrashReporting()

Adding a custom key-value segment to a crash report

You can add a key/value segments to crash report, like for example, which specific library or framework version you used in your app, so you can figure out if there is any correlation between specific library or other segment and crash reports.

Use the following function for this purpose:

Countly.sharedInstance().setCustomCrashSegments(Map<String, String> segments)

Adding breadcrumbs

Following command adds crash breadcrumb like log record to the log that will be send together with crash report.

Countly.sharedInstance().addCrashLog(String record) 

Logging handled exceptions

You can also log handled exceptions on monitor how and when they are happening with the following command:

Countly.sharedInstance().logException(Exception exception)

Additional SDK features

Testing

You've probably noticed that we used Countly.CountlyMessagingMode.TEST in our example. That is because we're building the application for testing purposes for now. Countly separates users who run apps built for test and for release. This way you'll be able to test messages before sending them to all your users. When you're releasing the app, please use Countly.CountlyMessagingMode.PRODUCTION.

Push Notifications localization

While push notification messages in Countly Messaging are properly localized, you can also localize the way notifications are displayed. By default, Countly uses your application name for a title of notification alert and the English word "Open" for the alert button name. If you want to customize it, pass an array of Strings, where the button name is the first value, to initMessaging call:

String[] pushLocalizationArray = new String[]{"Open"};
Countly.sharedInstance()
    .init(this, "YOUR_SERVER", "APP_KEY", null, DeviceId.Type.ADVERTISING_ID)
    .initMessaging(this, CountlyActivity.class, "PROJECT_ID", Countly.CountlyMessagingMode.TEST, pushLocalizationArray);

Geolocation-aware notifications (Enterprise Edition only)

You can send notifications to users located at predefined locations. By default, Countly uses geoip database in order to bind your app users to their location. But if your app has access to better location data, you can submit it to the server:

double latitude = 12;
double longitude = 22;

Countly.sharedInstance().setLocation(latitude, longitude);

View tracking

View tracking is a means to report every screen view to Countly dashboard. In order to enable automatic view tracking, call:

Countly.sharedInstance().setViewTracking(true);

Also you can track custom views with following code snippet:

Countly.sharedInstance().recordView("View name")

To review the resulting data, open the dashboard and go to Analytics > Views. For more information on how to use view tracking data to it's fullest potential, look for more information here.

Receiving and showing badge number from push notifications

Minimum Countly Server Version

This feature is supported only on servers with the minimum version 16.12.2.

While showing badges isn't supported natively for versions before Android O, there are some devices and launchers that support it. Therefore you may want to implement such a feature in your app but not that not all devices will support badges.

While creating a new message in the messaging overview and preparing it's content, there is a optional option called "Add iOS badge". You can use that to send badges also to Android devices.

Adding a badge number to an application while sending a notification

Adding a badge number to an application while sending a notification

In order to receive this badge number in your application, you have to subscribe to the broadcasts about received messages. There, you are informed about all received push notifications using Message and bundle. The badge number is sent with the key "badge". You can use that to extract the badge number from the received bundle and then use it to display badge numbers with your implementation of choice.

In the below example we will use a badge library called ShortcutBadger, which is used to show badges on Android. Follow their instructions in this link on how to use it in your Androidproject. You can also see the same example inside Countly messaging sample project.

/** Register for broadcast action if you need to be notified when Countly message received */
messageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Message message = intent.getParcelableExtra(CountlyMessaging.BROADCAST_RECEIVER_ACTION_MESSAGE);
        Log.i("CountlyActivity", "Got a message with data: " + message.getData());

        //Badge related things
        Bundle data = message.getData();
        String badgeString = data.getString("badge");
        try {
            int badgeCount = Integer.parseInt(badgeString);

            boolean succeded = ShortcutBadger.applyCount(getApplicationContext(), badgeCount);
            if(!succeded) {
                Toast.makeText(getApplicationContext(), "Unable to put badge", Toast.LENGTH_SHORT).show();
            }
        } catch (NumberFormatException exception) {
            Toast.makeText(getApplicationContext(), "Unable to parse given badge number", Toast.LENGTH_SHORT).show();
        }
    }
};
IntentFilter filter = new IntentFilter();
filter.addAction(CountlyMessaging.getBroadcastAction(getApplicationContext()));
registerReceiver(messageReceiver, filter);

Checking if init has been called

In case you want to check if init has been called, you can just use the following function:

Countly.sharedInstance().isInitialized();

Checking if onStart has been called

For some applications there might a use case where the developer would like to check if the Countly sdkonStart function has been called. For that they can use the following call:

Countly.sharedInstance().hasBeenCalledOnStart();

Ignoring app crawlers

Sometimes server data might be polluted with app crawlers which are not real users, and you would like to ignore them. Starting from the 17.05 release it's possible to do that filtering on the app level. The current version does that using device names. Internally the Countly sdk has a list for crawler device names, if a device name matches one from that list, no information is sent to the server. At the moment that list has only one entry: "Calypso AppCrawler". In the future we might add more crawler device names if such are reported. If you have encountered a crawler that is not in that list, but you would like to ignore, you can add it to your sdk list yourself by calling addAppCrawlerName. Currently by default the sdk is ignoring crawlers, if you would like to change that, use ifShouldIgnoreCrawlers. If you want to check if the current device was detected as a crawler, use isDeviceAppCrawler. Detection is done in the init function, so you would have to add the crawler names before that and do the check after that.

//set that the sdk should ignore app crawlers
Countly.sharedInstance().ifShouldIgnoreCrawlers(true);

//set that the sdk should not ignore app crawlers
Countly.sharedInstance().ifShouldIgnoreCrawlers(false);

//add another app crawler device name to ignore
Countly.sharedInstance().addAppCrawlerName("App crawler");

//returns true if this device is detected as a app crawler and false otherwise
Countly.sharedInstance().isDeviceAppCrawler();

Android SDK