AppsFlyer SDK Integration - Android

  • Advertisers
  • Developers

android.pngSDK Version:  4.8.18 (Release Notes)

1. Overview

AppsFlyer's SDK provides app installation and event tracking functionality. We have developed an SDK that is highly robust (7+ billion SDK installations to date), secure, lightweight and very simple to embed.

You can track installs, updates and sessions and also track additional in-app events beyond app installs (including in-app purchases, game levels, etc.) to evaluate ROI and user engagement levels.


The AppsFlyer Android SDK is compatible with Android OS version 2.3 and above.

The SDK is also compatible with non-mobile Android based platforms such as Smart TVs, including Amazon's Fire TV.

For apps developed for Amazon's Fire TV, use AppsFlyer's Tracking Out of Store Solution.

If you're migrating from AppsFlyer's Android SDK V.3.3.x click here.


2. Quick Start

2.1 SDK Download

To download the latest AppsFlyer Android SDK jar, click here.

To verify the integrity of the SDK download, click here.

For details of AppsFlyer's Sample App, click here.

2.2 Embedding SDK in App

You can integrate the AppsFlyer's SDK either automatically using Gradle's Dependency Management or manually as an SDK.jar.

2.3 Adding the SDK to your Project

The simplest way to integrate the SDK into your project is by using Gradle's Dependency Management. Version info can be found here.

If you are not using Gradle, download and add the AF-Android-SDK.jar to the project's class path.

Adding AppsFlyer's Android SDK Dependency:

  1.  Open your project (or create a new project), and then open your_app | build.gradle
  2.  Add this to Module-level /app/build.gradle before dependencies:
repositories { 
  1. Add the implementation dependency with the latest version of the AppsFlyer SDK.
  2. Add this to Module-level /app/build.gradle after repository:
dependencies {
	implementation 'com.appsflyer:af-android-sdk:4+@aar'
	implementation ''


  • The '' dependency is required to support Google's Play Install referrer API. Using this API improves attribution accuracy, protects from install fraud and more.
  • The API is supported from AppsFlyer's Android SDK version 4.8.6 and onwards. If updating from an older SDK version complete this new dependency's integration by updating the SDK's init method.
  • Developers who are using ProGuard and want to use Google's new referrer API must set the following ProGuard rule: -dontwarn
  • Developers who are not using gradle build or aar and want to use Google's new referrer API must manually add jar as a file, and ensure that the following permission is added:

2.4 Setting the Required Permissions

The AndroidManifest.xml should include the following permissions:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Optional : -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

2.5 Setting the BroadcastReceiver in AndroidManifest.xml

The following two options are available for implementing the install referrer broadcast receiver:

Using a Single Broadcast Receiver Using a Multiple Broadcast Receiver

If you do not have a receiver listening on the INSTALL_REFERRER, in the AndroidManifest.xml, add the following receiver within the application tag:


	<receiver android:name="com.appsflyer.SingleInstallBroadcastReceiver" android:exported="true">
			 <action android:name="" />



If you get the error "Unresolved class SingleInstallBroadcastReceiver" after adding the receiver to AndroidManifest.xml, make sure to build the app first.

3. SDK Initialization

Initialization of the SDK is completed in two stages. In the first stage the DevKey is supplied along with an optional conversionDataListener. In the second stage the call to startTracking indicates that all relevant preparations are complete (e.g. call setCustomerUserId) and the SDK can start tracking all events.

To initialize the SDK, add the following code in your Application onCreate() function:

import com.appsflyer.AppsFlyerLib;
import com.appsflyer.AppsFlyerConversionListener;

public class AFApplication extends Application {
   private static final String AF_DEV_KEY = "";
   public void onCreate() {
       AppsFlyerConversionListener conversionDataListener = 
       new AppsFlyerConversionListener() {
       AppsFlyerLib.getInstance().init(AF_DEV_KEY, conversionDataListener, getApplicationContext());
       AppsFlyerLib.getInstance().startTracking(this);   }


Alternatively, you can delay the call to startTracking and place it within any relevant Activity OnCreate() function.


The following dependency: implementation '' And the getApplicationContext() passed in the following method: AppsFlyerLib.getInstance().init(AF_DEV_KEY, getConversionListener(), getApplicationContext()); are the prerequisite for reporting Google's New Referrer API to AppsFlyer.

Your dev key is accessible from the AppsFlyer Dashboard under the Configuration section inside App Settings:

This API enables AppsFlyer to detect installations, sessions, and updates.

4. Tracking In-App Events

In-App Events provide insight on what is happening in your app. It is recommended to take the time and define the events you would like to measure to allow you to track ROI (Return on Investment) and LTV (Lifetime Value).

Tracking in-app events is performed by calling trackEvent with event name and value parameters. See In-App Events documentation for more details.


An In-App Event name must be no longer than 45 characters. Events names with more than 45 characters do not appear in the dashboard, but only in the raw Data, Pull and Push APIs.

//context - use getApplicationContext()
//eventName is any string to define the event name.
//eventValues is a map of event parameters that comprise a rich event.  
public static void trackEvent(Context context, String eventName, Map eventValues);

: Level Achieved In-App Event

Map<String, Object> eventValue = new HashMap<String, Object>();

This generates an event of type af_level_achieved with the following event values:
{af_level: 9, af_score: 100}


  • AppsFlyer supports non-English characters with in-app events, or with any other SDK API, starting from Android SDK version 4.8.1.
  • Do not add any currency symbol or commas to the figures, as these are not recognized.

 Usage Example

Map<String,Object> eventValues = new HashMap<>();
eventValues.put(AFInAppEventParameterName.REVENUE, 1200);
eventValues.put(AFInAppEventParameterName.CURRENCY, "JPY");
AppsFlyerLib.getInstance().trackEvent(this, AFInAppEventType.PURCHASE, eventValues);

5. Tracking Deep Linking


We highly recommend to have Deep Linking integrated in your app. Deep Linking is a crucial part of retargeting campaigns and it is highly recommended to use when running retargeting campaigns.

For each activity that may be used for deep linking (including the main activity if needed) add the following line in the onCreate():


Activities that are meant to be opened by deep linking should have the below intent filter on the activity definitions in the manifest file. 

   <action android:name="android.intent.action.VIEW" />
   <category android:name="android.intent.category.DEFAULT" />
   <category android:name="android.intent.category.BROWSABLE" />
   <data android:scheme="yourUniquescheme" />

Scheme configured correlates with the af_dp value you include in your tracking link.

To receive your deep link data, you must implement the callback onAppOpenAttribution called by the AppsFlyer SDK.  It returns the Onelink/tracking link parameters used to trigger the app open. Then, you can parse the values and apply the logic to trigger the relevant app page.

void onAppOpenAttribution(Map<String,String> attributionData);

For more information, click here, or review this article’s Get Conversion Data section.

6. Tracking Revenue

Use the af_revenue (AFInAppEventParameterName.REVENUE) event parameter to count revenue as part of an in-app event. You can populate it with any numeric value, positive or negative.


af_revenue is the ONLY event parameter that is counted on AppsFlyer as real revenue on the raw data and dashboard. For more details please click here.

Example: Revenue In-App Event

Map<String, Object> eventValue = new HashMap<String, Object>();
AppsFlyerLib.getInstance().trackEvent(getApplicationContext() , AFInAppEventType.PURCHASE , eventValue);

This generates an event of type af_purchase with the following event values:

{af_content_id: “1234567”, af_content_type: “category_a”, af_revenue: 200, af_currency: “USD”}

The purchase event above contains a $200 revenue, appearing as revenue in the dashboard. 


Setting user local currency code for in-app purchases - the currency code should be a 3 character ISO 4217 code. (default is USD). 

You can set the currency code for all events by calling the following method: AppsFlyer.setCurrencyCode("GBP");


Do NOT format the revenue value in any way. It should not contain comma separators, currency sign, or text. A revenue event should be similar to 1234.56, for example.

Tracking Negative Revenue

If you need to track negative revenue for example when a user cancels a purchase or receives a refund, you can send negative revenue.

Map<String, Object> eventValue = new HashMap<String, Object>();
AppsFlyerLib.getInstance().trackEvent(getApplicationContext() , "cancel_purchase" , eventValue);


Notice the following in the code above:

  1. The revenue value is preceded by a minus sign
  2. The event name has a unique value of "cancel_purchase" - to allow you to identify negative revenue events in the dashboard and raw data reports

7. Get Conversion Data

AppsFlyer allows you to access the user attribution data in real-time for every new install, directly from the SDK level. By doing this you can serve users with personalized content or send them to specific activities within the app, which can greatly enhance their engagement with your app.

To access AppsFlyer's conversion data from the Android SDK implement the ConversionDataListener:

public interface AppsFlyerConversionListener {
       void onInstallConversionDataLoaded(Map<String,String> conversionData);
        void onInstallConversionFailure(String errorMessage);


AppsFlyerLib.getInstance().registerConversionListener(this, new AppsFlyerConversionListener() {
  public void onInstallConversionDataLoaded(Map<String, String> conversionData) {
      for (String attrName : conversionData.keySet()) {
          Log.d(AppsFlyerLib.LOG_TAG, "attribute: " + attrName + " = " + conversionData.get(attrName));
  public void onInstallConversionFailure(String errorMessage) {
      Log.d(AppsFlyerLib.LOG_TAG, "error getting conversion data: " + errorMessage);
  public void onAppOpenAttribution(Map<String, String> conversionData) {
  public void onAttributionFailure(String errorMessage) {
      Log.d(AppsFlyerLib.LOG_TAG, "error onAttributionFailure : " + errorMessage);

8. User Identifiers

Get AppsFlyer Device ID

AppsFlyer's unique device ID is created for every new install of an app. Use the following API to obtain AppsFlyer’s Unique ID:

public String getAppsFlyerUID(Context context);

Usage Example:

String appsFlyerId = AppsFlyerLib.getInstance().getAppsFlyerUID(this);

Set Customer User ID

Setting your own customer ID enables you to cross-reference your own unique ID with AppsFlyer’s unique ID and the other devices’ IDs. This ID is available in AppsFlyer CSV reports along with Postback APIs for cross-referencing with your internal IDs.

To set your Customer User ID:

public void setCustomerUserId(String id);


Usage Example:



It is recommended to set your Customer User ID as soon as possible as it is only associated to events reported after its setup. If setCustomerUserId is called before calling startTracking, you will have the Customer User ID in the raw export for installs and for events. If it is set after, you will see the value only for events tracked after calling this method.

Customer User ID can also be used to complete integrations with Analytics platforms such as Mixpanel and Swrve.


Getting Customer User ID:

To avoid setting the customer user ID value again beyond the first launch you can check if its value is empty or not by using


For more information about the Customer User ID, click here.

Set User Email

AppsFlyer enables you to report one or more of the device’s associated email addresses. You must collect the email addresses and report it to AppsFlyer according to your required encryption method.

The following encryption methods are available: SHA1, MD5, SHA256 and plain.


public void setUserEmails(String... emails);

Usage Example:

AppsFlyerLib.getInstance().setUserEmails(AppsFlyerProperties.EmailsCryptType.MD5, "","", ….);


Personally Identifiable Information (PII) such as email addresses are not retained by AppsFlyer and this information is not presented in any reports. The purpose of collecting this information is solely for postback purposes to the media source.

Google Advertising ID

From SDK Version 4.8.0 AppsFlyer automatically collects the google_advertising_id. The requirement to collect the Google Advertising ID is only relevant for SDK versions 4.7.X and below.

IMEI and Android ID

By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat (4.4) and the device contains Google Play Services (on SDK versions 4.8.8 and below the specific app needed GPS). 

To explicitly send these IDs to AppsFlyer, developers can use the following APIs and place it before the startTracking code:


If the app does NOT contain Google Play Services, the IMEI and Android ID are collected by the SDK. However, apps with Google play services should avoid IMEI collection as this is in violation of the Google Play policy.

Developers can opt-out of collection of IMEI and Android ID by using these APIs:



At least one device identifier, GAID, Android ID or IMEI, MUST be collected to allow for proper attribution.

9. Optional Features

Measure Uninstalls

AppsFlyer enables you to measure the uninstalls rate of users coming from different sources.

To complete this process fully and correctly read here.

Tracking Push Notifications

AppsFlyer allows you to measure push notifications as part of a retargeting campaign.

To enable this feature, call the next method inside the onCreate method of every Activity which will be launched upon clicking the notification:


The data payload should include an object: af with the relevant key-value string:





For more information on push notification measurement, read here.

Cross Promotion Tracking

AppsFlyer allows you to track and attribute installs originating from a cross promotion of one of your apps from within the current app the user has. Cross promoting apps can be a major growth factor in driving additional installs for your apps.

For details, see the Cross Promotion Tracking article, here.

User Invite Tracking

AppsFlyer allows you to track and attribute installs originating from user invites within your app. Allowing your existing users to invite their friends and contacts as new users to your app can be a key growth factor for your app.

For details, see the User Invite Tracking article, here.

Set Currency Code

You can set a global currency code using the API below, in addition to specific currency codes that can be used as part of each in-app event sent to AppsFlyer. The global currency code is used when af_currency


is not sent as part of an in-app event.

USD is the default value. You can find acceptable ISO currency codes here.

Use the following API to set the currency code:

public void setCurrencyCode(String currencyCode);

Usage Example:


In-App Purchase Validation

AppsFlyer’s SDK provides server verification for in-app purchases. To set purchase validation tracking, call the validateAndTrackInAppPurchase method inside the onActivityResult function.

This call automatically generates an af_purchase in-app event.

public static void validateAndTrackInAppPurchase(Context context, 
String publicKey, String signature, String purchaseData, 
String price, String currency, HashMap<String, String> additionalParameters);

This call has two callback blocks, one for ‘Success’ and one for ‘Failure’ (for any reason, including validation fail).

     AppsFlyerInAppPurchaseValidatorListener() {
          public void onValidateInApp() {
              Log.d(TAG, "Purchase validated successfully");
          public void onValidateInAppFailure(String error) {
              Log.d(TAG, "onValidateInAppFailure called: " + error);

Usage Example:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   if (requestCode == 1001) {
       String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
       String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
       if (resultCode == RESULT_OK) {
           HashMap<String,String> event = new HashMap<>();
           AppsFlyerLib.getInstance().validateAndTrackInAppPurchase(getApplicationContext(),publicKey, dataSignature, purchaseData, "3.00", "ILS", event);


Calling validateAndTrackInAppPurchase automatically generates an af_purchase in-app event. There is no need to send this event yourself.

Anonymize User Data

AppsFlyer provides you with a method to anonymize specific user identifiers in AppsFlyer analytics. This method complies with the latest privacy requirements and complies with Facebook data and privacy policies. Default is NO, meaning no anonymization is performed by default.

Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions:

public void setDeviceTrackingDisabled(boolean isDisabled);

Usage Example:


Tracking can be restarted by calling deviceTrackingDisabled again set to false.


Anonymizing users SEVERELY impacts your attribution information.
Use this option ONLY for regions which legally prevents you from collecting your users' information.

Custom Time Between Sessions

By default, at least 5 seconds must lapse between 2 app launches to count as separate 2 sessions (more about counting sessions).
However, you can use the following API to set your custom value for the minimum required time between sessions:
AppsFlyerLib.setMinTimeBetweenSessions(int seconds);

Note that setting a high value to the custom time between launches may badly impact APIs relying on sessions data, such as deep linking.

Background Sessions for Utility Apps

If your app is a utility app running in the background you can use this API in your activity’s onCreate() -

public void reportTrackSession(Context context);

Usage Example:


Track Out-of-Store Apps


Google Play is the default store. If you are publishing your app only on Google Play, skip this section.

To track installs out of Google Play, set the channel/store at the app’s AndroidManifest.xml with a unique channel or any store name for each APK. The CHANNEL value is case sensitive.


<meta-data android:name="CHANNEL" android:value="Amazon" />
<meta-data android:name="CHANNEL" android:value="Standalone"/>
<meta-data android:name="CHANNEL" android:value="Verizon" />


You must configure the CHANNEL value at the AppsFlyer dashboard when setting up the app.

Place the meta-data tag before the </application> tag.

For more details on how to track installs for out-of-store apps, read here.


In some extreme cases you might want to shut down all SDK tracking due to legal and privacy compliance. This can be achieved with the isStopTracking API. Once this API is invoked, our SDK no longer communicates with our servers and stops functioning.

AppsFlyerLib.getInstance().stopTracking(true, context);

There are several different scenarios for user opt-out. We highly recommend following the exact instructions for the scenario, that is relevant for your app.

In any event, the SDK can be reactivated by calling the same API, by passing false.


Do not call trackAppLaunch if isStopTracking is set to true

To start tracking again once stopTracking is set to false, use the following SDK API:

AppsFlyerLib.getInstance().trackAppLaunch(getApplicationContext(), AF_DEV_KEY);


Use the stopTracking API only in cases where you want to fully ignore this user from any and all tracking. Using this API SEVERELY impacts your attribution, data collection and deep linking mechanism.

Delay SDK init for customerUserID

It is possible to delay the SDK Initialization until the customerUserID is set. This feature makes sure that the SDK doesn't begin functioning until the customerUserID is provided. If this API is used, all in-app events and any other SDK API calls are discarded, until the customerUserID is provided and tracked.

To indicate that the SDK should delay initialization for the customer user id call


immediately before the init() method. The rest of the SDK initialization should remain unchanged.

Once the customerUserID has been provided, call

AppsFlyerLib.getInstance().setCustomerIdAndTrack("customer_id", this);

to provide the SDK with the relevant customer user id and trigger the SDK to begin its normal tracking.

The code should appear as follows:
public class AFApplication extends Application {
   private static final String AF_DEV_KEY = ;
   public void onCreate() {
       AppsFlyerConversionListener conversionDataListener = 
       new AppsFlyerConversionListener() {
       AppsFlyerLib.getInstance().init(AF_DEV_KEY, getConversionListener(), getApplicationContext());
       // Do your magic to get the customerUserID
       // ...
       // any AppsFlyer SDK code invoked here will be discarded
      //Call the following API once the customerUserID is available:
 AppsFlyerLib.getInstance().setCustomerIdAndTrack("customer_id", this);


Use this API only in cases where it is appropriate for your business logic. Using this API increases the chance for discrepancies and might make the app more exposed to fraud.

Setting Additional Custom Data

The setAdditionalData API is required to integrate on the SDK level with several external partner platforms, including Segment, Adobe and Urban Airship. Use this API only if the integration article of the platform specifically states setAdditionalData API is needed.
The following is a code example for implementing setAdditionalData on Android:

HashMap<String,Object> CustomDataMap = new HashMap<>();

Attribution for Pre-Installed Apps

There are various methods available for Android attribution for pre-installed apps.

For details, click here.

Setting a Tracking Request Listener

If you want to receive a confirmation that the tracking request was successfully received by the AppsFlyer servers, it is possible to implement the AppsFlyerTrackingRequestListener listener.

The onTrackingRequestSuccess() callback method is invoked for every 200 response to an attribution request made by the SDK.

The onTrackingRequestFailure(String error) callback method is invoked for any other response and returns the response as the error string.

Implementation Example

AppsFlyerLib.getInstance().startTracking(this.getApplication(),"devKey", myListener());
private AppsFlyerTrackingRequestListener myListener() {   
    return new AppsFlyerTrackingRequestListener() {  
        @Override public void onTrackingRequestSuccess() { 
            Log.d("Debug", "Got 200 response from server");    
        }   @Override public void onTrackingRequestFailure(String error) { 
            Log.d("Debug", error); 

10. Testing the SDK Integration

To test the SDK integration before and after submitting to the Google Play Store click here.

Now you can start tracking the media sources you work with.

11. Known Issues

If you are using ProGuard and you encounter a warning regarding our AFKeystoreWrapper class, then add the following code to your ProGuard rules file:

-keep class com.appsflyer.** { *; }
Was this article helpful?
17 out of 20 found this helpful


  • Hi Everyone,

    The Android SDK has been updated to version 4.8.13.

    The new version fixes a bug in edge cases where the IMEI was missing when passed explicitly through the setImeiData API.

  • Hi Everyone,

    The Android SDK has been updated to version 4.8.14.

    This new version has:

    * Added setOutOfStore and getOutOfStore APIs for dynamically setting the AF_STORE value

    * Added onTrackingRequestFailure and onTrackingRequestSuccess APIs for receiving a confirmation that the tracking request was successfully received by the AppsFlyer servers.

  • Hello Everyone,

    We're happy to announce the release of Android SDK version 4.8.15.

    This new version SDK support 4 new events:
    Subscribe, Start Trial, Ad Click, Ad View

    In addition, standard events have been mapped for future support of Facebook's enhanced Ad Event Optimization.

Please sign in to leave a comment.