ayeT-Studios Publisher Android SDK Integration Guide (v3.0)



Updates

2018-11-29: v3.0 - Full support for API 26+ build targets, bugfixes, simplified use & improved handling under poor network conditions
2018-07-02: v2.1 - Fixed video ad orientation & resolution issues on Android 8.1
2018-06-18: v2.0 - Video Ads & Rewarded Video Ads
2017-11-01: v1.1 - Fixed incompatibilities with present GSON dependencies
2017-10-29: v1.0 - Initial Release of our Publisher SDK (Android)


Quick 2.1 To 3.0 Migration Guide

- remove the PACKAGE_ADDED BroadcastReceiver from AndroidManifest.xml
- add INSTALL_REFERRER BroadcastReceiver to AndroidManifest.xml (see topic 3)
- call AyetSdk.init(...) with "getApplication()" instead of "getApplicationContext()"


Quick 1.1 To 2.1 (Video Ads) Migration Guide

- add video activity to AndroidManifest.xml (see topic 3)
- update your proguard-rules file (see topic 9)


Introduction

The ayeT-Studios Publisher SDK allows you to easily monetize your app and reward your users with in-app currency. Your users get access to our offerwalls, allowing them to earn currency for completing tasks such as trying new apps, answering surveys, signing up for free trials or watching video ads. The integration is simple, allows both managed (our servers store user information and balances) and unmanaged (you receive callbacks and handle user wallets yourself) currencies and also works well alongside traditional in-app purchases.




Topics

  1. Prerequisites
  2. Download the library
  3. Add the library to your Android Studio project
  4. Initialize the SDK & Receive Managed Balances
  5. Show the Offerwall
  6. Show Video Ads
  7. Show Rewarded Video Ads
  8. Appendix I: Unmanaged Currency Handling / Conversion Callbacks
  9. Appendix II: Proguard Rules / Release Builds
  10. Appendix III: Multiple INSTALL_REFERRER Receivers





1. Prerequisites


Before integrating the SDK in your app, you should sign up for a publisher account. Afterwards login as publisher and create a new Android App Placement using the correct package name you intend to use for your final app.
This is important since we'll generate an APP_KEY / Identifier for you which has to be added to your AndroidManifest (see step 3).

2. Download the library


You can download the lastest version of our publisher library here:
ayetpublisher3.0.jar

3. Add the library to your Android Studio project


Copy the downloaded jar library to your Android Studio project (in the app/libs/ folder).
Go to "Module Settings" (F12 or right-click your app in the Project View) and check the dependencies tab to make sure the library is added as a file dependency and set to "Compile":




Afterwards open your AndroidManifest.xml and add our offerwall activity to your application scope:

<activity android:name="com.ayetstudios.publishersdk.OfferwallActivity" android:configChanges="orientation|screenSize" />
<activity android:name="com.ayetstudios.publishersdk.VideoActivity" android:configChanges="orientation|screenSize" />	                


Another AndroidManifest.xml requirement is your AYET_APP_KEY which you can fetch from our publisher dashboard (called Identifier there) after adding an app placement for your package name - add it to the application scope as well:

<meta-data android:name="AYET_APP_KEY" android:value="xxxxxxxxxxxxxxxx" />	                


Add the "INSTALL_REFERRER" broadcast receiver right before the closing </application> tag in the AndroidManifest.xml:

<receiver android:name="com.ayetstudios.publishersdk.TrackingReceiver" android:exported="true" android:enabled="true">
    <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
        <data android:scheme="package" />
    </intent-filter>
</receiver>	                
Hint: If you already have an INSTALL_REFERRER broadcast receiver declared or other libraries using INSTALL_REFERRER as well, check out Appendix III: Multiple INSTALL_REFERRER Receivers.


Also make sure to check your permissions in the AndroidManifest.xml:

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


This is an example for a complete AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="into.myapplication">

    <uses-permission android:name="android.permission.INTERNET" />  <!-- mandatory permission -->

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />  <!-- optional -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- optional -->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

	<!-- Publisher SDK Specific-->
        <activity android:name="com.ayetstudios.publishersdk.OfferwallActivity" android:configChanges="orientation|screenSize"></activity>
        <activity android:name="com.ayetstudios.publishersdk.VideoActivity" android:configChanges="orientation|screenSize"></activity>

        <!-- Publisher SDK Specific-->
        <meta-data android:name="AYET_APP_KEY" android:value="xxxxxxxxxxxxxxxx" />

        <!-- Publisher SDK Specific-->
        <receiver android:name="com.ayetstudios.publishersdk.TrackingReceiver" android:exported="true" android:enabled="true">
            <intent-filter>
                <action android:name="com.android.vending.INSTALL_REFERRER" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>

    </application>

</manifest>	                

4. Initialize the SDK & Managed User Balances


In this step, we are going to initialize the SDK in the main activity. We also use callbacks to track the user's account balance - this is optional and not required if you're planning to manage user balances on your own servers.
Hint: If you do not supply a user identifier, we track account balances by device. Otherwise balances will be credited and stored for the identifier (e.g. username, hashed email address, etc.).
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    AyetSdk.init(getApplication(), "username (optional)", new UserBalanceCallback() { // UserBalanceCallback is optional if you want to manage balances on your servers
            @Override
            public void userBalanceChanged(SdkUserBalance sdkUserBalance) {
                Log.d("AyetSdk" , "userBalanceChanged - available balance: "+sdkUserBalance.getAvailableBalance()); // this is the new total available balance for the user
            }

            @Override
            public void userBalanceInitialized(SdkUserBalance sdkUserBalance) {
                Log.d("AyetSdk" , "SDK initialization successful");
                Log.d("AyetSdk" , "userBalanceInitialized - available balance: "+sdkUserBalance.getAvailableBalance()); // this is the total available balance for the user
                Log.d("AyetSdk" , "userBalanceInitialized - spent balance: "+sdkUserBalance.getSpentBalance()); // this is the total amount spent with "AyetSdk.deductUserBalance(..)"
                Log.d("AyetSdk" , "userBalanceInitialized - pending balance: "+sdkUserBalance.getPendingBalance()); // this is the amount currently pending for conversion (e.g. user still has offer requirements to meet)
            }
            
            @Override
            public void initializationFailed() {
                Log.d("AyetSdk", "initializationFailed - please check APP API KEY & internet connectivity");
            }
        });

    setContentView(R.layout.activity_main);
}	                


If you want to make sure the SDK has been initialized and is ready to display the offerwall or video ads, you can use the following function:
if (AyetSdk.isInitialized()) {
    Log.d("AyetSdk" , "SDK is ready");
} else {
    Log.d("AyetSdk" , "SDK is NOT ready");
}	                


If you want to spend user currency, for example if the user clicks a "purchaseInAppItem" button, you can utilize the deductUserBalance function:

mPurchaseInAppItemButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        int amount=100;
        AyetSdk.deductUserBalance(getApplication(), amount, new DeductUserBalanceCallback() {
            @Override
            public void success() {
                Log.d("AyetSdk" , "deductUserBalance - successful, new available balance: "+AyetSdk.getAvailableBalance());
                // TODO: activate the purchased content
            }

            @Override
            public void failed() {
                Log.d("AyetSdk" , "deductUserBalance - failed");
                // this usually means that the user does not have sufficient balance in his account
            }
        });
    }
});	                

5. Show the Offerwall


Showing the offerwall is straight-forward, you can simply call showOfferwall from any Activity:

AyetSdk.showOfferwall(getApplication());	                
showOfferwall starts our offerwall activity and displays available tasks for the user to complete.

6. Show Video Ads


Introduction to video ads

Video ads are a great way to monetize your apps & games. Compared to banner or static interstitial ads, they deliver an outstanding eCPM and are widely accepted by users - if implemented correctly.
While video ads are non incentivized offers which either pay the publisher per view (CPM) or per installation / action (CPI / CPA), we give publishers the opportunity to reward their users for watching an optional (skippable) "rewarded" video ad.
Regardless of the video ad type, it's strictly forbidden to prompt users to install apps or interact with the promoted assets.

Normal video ads work like TV commercials. They are between 15s and 30s long and cannot be interrupted. A typical use case is a commercial break in games between levels.
Rewarded video ads are optional and user initiated. Users can skip rewarded ads at any point, but will be rewarded with in-app items or virtual currency if they watch it completely.

Normal videos are not limited in terms of frequency and capping, but for rewarded video ads it's strongly advised to check and configure the placement correctly (Settings > Rewarded Video Ads > Rewarded Video Capping & Frequency) to prevent abuse.

Both video ads and rewarded video ads send publisher earning callbacks without user or device information (so only offer information and payout_usd is set) if your callback URL is configured in the placement overview.
Please note that for CPM offers, it's possible that multiple views for a campaign are grouped into one earning and callback to avoid congestion.

Rewarded video ads can additionally (and independently from publisher earning callbacks) send user currency callbacks, if Settings > Rewarded Video Ads > Enable S2S View Callbacks is enabled. Given that the placement callback url is set and the currency amount per rewarded video view is greater than 0, this will send a S2S callback for each completed rewarded video view (currency_amount is set, but payout_usd is always 0).
Before starting to implement video ads, please make sure that this ad format has been enabled for your placement.
If not, go to Placement > Settings > Video Ads and request access or contact your account manager to have them enabled.


To show a non-interruptable, fullscreen video ad (15-30 seconds depending on your placement video settings), you can make the following showVideoAd call:
AyetSdk.showVideoAd(getApplication(), AyetSdk.FLAG_DEFAULT, new VideoCallbackHandler() {
        @Override
        public void nofill() {
            // This is called when either no video is available to watch, the AyetSdk has not been initialized or there were network/connectivity issues
            Log.d(TAG , "AyetSdk.showVideoAd::nofill()");
        }
        @Override
        public void finished() {
            // This is called when the video activity is done (video completed, aborted or other problems like network speed)
            Log.d(TAG , "AyetSdk.showVideoAd::finished()");
        }
        @Override
        public void willBeShown() {
            // This is called after selecting a video and right before the video activity is started to play it
            Log.d(TAG , "AyetSdk.showVideoAd::willBeShown()");
        }
    });	                

If you want to restrict video ads to wifi connectivity only, you can append the AyetSdk.FLAG_WIFI_ONLY flag:
AyetSdk.showVideoAd(getApplication(), AyetSdk.FLAG_DEFAULT | AyetSdk.FLAG_WIFI_ONLY, new VideoCallbackHandler() {...	                

By default, videos will be shown in their optimized orientation (which is landscape in most cases). If your app should strictly stay in a fixed orientation, you can utilize the AyetSdk.FLAG_ORIENTATION_PORTRAIT or AyetSdk.FLAG_ORIENTATION_LANDSCAPE flags to enforce the video orientation:
AyetSdk.showVideoAd(getApplication(), AyetSdk.FLAG_DEFAULT | AyetSdk.FLAG_ORIENTATION_PORTRAIT, new VideoCallbackHandler() {...	                


Another capability of the SDK is to asychronously request a video ad. This gives you the opportunity to decide whether the video should actually play or if it should be discarded.
Hint: The average request-to-play time is around 1.5-3 seconds for video ads under good network conditions.
To request a video ad asynchonously, you can use the following code (note the different callback interface):
AyetSdk.showVideoAd(MainActivity.this, AyetSdk.FLAG_DEFAULT | AyetSdk.FLAG_ASYNC, new VideoAsyncCallbackHandler() {
        @Override
        public void nofill() {
            // This is called when either no video is available to watch, the AyetSdk has not been initialized or there were network/connectivity issues
            Log.d(TAG , "AyetSdk.showVideoAdAsync::nofill()");
        }
        @Override
        public void finished() {
            // This is called when the video activity is done (video completed, aborted or other problems like network speed)
            Log.d(TAG , "AyetSdk.showVideoAdAsync::finished()");
        }
        @Override
        public void willBeShown() {
            // This is called after selecting a video, after "videoAd.showVideo()" has been called in "ready(...)" and right before the video activity is started to play it
            Log.d(TAG , "AyetSdk.showVideoAdAsync::willBeShown()");
        }
        @Override
        public void ready(final VideoAdInterstitial videoAd) {
            // This is called when a video has been selected and is ready to be shown. You have about 60 seconds to decide whether you want to play the video by calling "videoAd.showVideo();"
            // If showVideo isn't called, the video will be discarded and the video activity won't start.

            Log.d(TAG , "AyetSdk.showVideoAdAsync::ready()");

			// As an example, we're starting a timer task here who is signaling the SDK to show the prefetched video after a delay of 4 seconds
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    videoAd.showVideo();
                }
            } , 4000);
        }
    });
                

7. Show Rewarded Video Ads


Introduction to video ads

Video ads are a great way to monetize your apps & games. Compared to banner or static interstial ads, they deliver an outstanding eCPM and are widely accepted by users - if implemented correctly.
While video ads are non incentivized offers which either pay the publisher per view (CPM) or per installation / action (CPI / CPA), we give publishers the opportunity to reward their users for watching an optional (skippable) "rewarded" video ad.
Regardless of the video ad type, it's strictly forbidden to prompt users to install apps or interact with the promoted assets.

Normal video ads work like TV commercials. They are between 15s and 30s long and cannot be interrupted. A typical use case is a commercial break in games between levels.
Rewarded video ads are optional and user initiated. Users can skip rewarded ads at any point, but will be rewarded with in-app items or virtual currency if they watch it completely.

Normal videos are not limited in terms of frequency and capping, but for rewarded video ads it's strongly advised to check and configure the placement correctly (Settings > Rewarded Video Ads > Rewarded Video Capping & Frequency) to prevent abuse.

Both video ads and rewarded video ads send publisher earning callbacks without user or device information (so only offer information and payout_usd is set) if your callback URL is configured in the placement overview.
Please note that for CPM offers, it's possible that multiple views for a campaign are grouped into one earning and callback to avoid congestion.

Rewarded video ads can additionally (and independently from publisher earning callbacks) send user currency callbacks, if Settings > Rewarded Video Ads > Enable S2S View Callbacks is enabled. Given that the placement callback url is set and the currency amount per rewarded video view is greater than 0, this will send a S2S callback for each completed rewarded video view (currency_amount is set, but payout_usd is always 0).
Before starting to implement video ads, please make sure that this ad format has been enabled for your placement.
If not, go to Placement > Settings > Video Ads and request access or contact your account manager to have them enabled.


Rewarded video ads give you a variety of options depending on your placement settings and in-app calls:

(1) Reward users with virtual currency for watching an ad and handle the currency on our servers ("managed currency")


This implementation is easy to integrate and useful if you're already using our offerwall with managed currencies. You can add a button to your app which allows users to watch a rewarded video and earn virtual currency.
Note that it's also possible to simply enable rewarded videos in the offerwall itself, without the need to implement a button on your own (check your placement settings for "Show Rewarded Videos In Offerwall").

Placement Settings:
  • Rewarded Video Ads > User Reward (per view) must be greater than 0
Code to show a rewarded video ad:
AyetSdk.showVideoAd(getApplication(), AyetSdk.FLAG_REWARDED, new RewardedVideoCallbackHandler() {
	@Override
	public void aborted() {
		// This is called when the user aborted / skipped a rewarded video ad
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::aborted()");
	}
	@Override
	public void completed(int amount) {
		// This is called when the user has watched a complete video ad was rewarded with "amount" virtual currency
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::completed()   currency amount added to the user balance on our servers: "+Integer.toString(amount));
	}
	@Override
	public void nofill() {
		// This is called when either no video is available to watch, the user ran into your configured frequency caps, the AyetSdk has not been initialized or there were network/connectivity issues
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::nofill()");
	}
	@Override
	public void finished() {
		// This is called when the video activity is done (video completed, aborted or other problems like network speed)
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::finished()");
	}
	@Override
	public void willBeShown() {
		// This is called after selecting a video and right before the video activity is started to play it
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::willBeShown()");
	}
});	                


(2) Reward users with virtual currency for watching an ad and handle the currency on your servers ("unmanaged currency" with S2S callbacks)


This implementation is more advanced but allows you to manage user currency and rewards serverside through S2S callbacks.

Placement Settings:
  • Rewarded Video Ads > User Reward (per view) must be greater than 0
  • Rewarded Video Ads > Enable S2S View Callbacks must be enabled
  • Overview > Callback Url must be set
Code to show a rewarded video ad:
The code implementation is the same as for (1). The difference is how you manage and spend virtual currency.

S2S Callbacks:
Note: The delay for S2S callbacks is usually below 60 seconds, but fluctuates depending on our callback server load.
Reward callbacks from video ads always have currency_amount set to your configured amount per view and payout_usd set to zero *.
Aside from this, see Appendix I: Unmanaged Currency Handling / Conversion Callbacks below for more information about callbacks and parameters.
* Payout / Revenue callbacks for videos are sent separately without user or device information.


(3) Reward users with in-app benefits for watching an ad and distribute the reward client-side in-app


This implementation is easy to integrate and has a variety of use cases. A common example is a "Game Over" screen, where you offer your users to watch a rewarded video ad to get an extra life. Others might be consumables, which can be collected or replenished by watching a short video.

Placement Settings:
  • Rewarded Video Ads > User Reward (per view) should be 0 if you're using the offerwall and your virtual currency for other purposes
  • Rewarded Video Ads > Enable S2S View Callbacks should be disabled
Code to show a rewarded video ad:
AyetSdk.showVideoAd(getApplication(), AyetSdk.FLAG_REWARDED, new RewardedVideoCallbackHandler() {
	@Override
	public void aborted() {
		// This is called when the user aborted / skipped a rewarded video ad
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::aborted()");
	}
	@Override
	public void completed(int amount) {
		// This is called when the user has watched a complete video ad and should be rewarded
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::completed() - GIVE EXTRA LIFE );
		MainActivity.this.giveExtraLife();
	}
	@Override
	public void nofill() {
		// This is called when either no video is available to watch, the user ran into your configured frequency caps, the AyetSdk has not been initialized or there were network/connectivity issues
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::nofill()");
	}
	@Override
	public void finished() {
		// This is called when the video activity is done (video completed, aborted or other problems like network speed)
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::finished()");
	}
	@Override
	public void willBeShown() {
	
		// This is called after selecting a video and right before the video activity is started to play it
		Log.d(TAG , "AyetSdk.showRewardedVideoAd::willBeShown()");
	}
});	                




By default, videos will be shown in their optimized orientation (which is landscape in most cases). If your app should strictly stay in a fixed orientation, you can utilize the AyetSdk.FLAG_ORIENTATION_PORTRAIT or AyetSdk.FLAG_ORIENTATION_LANDSCAPE flags to enforce the video orientation:
AyetSdk.showVideoAd(getApplication(), AyetSdk.FLAG_REWARDED | AyetSdk.FLAG_ORIENTATION_PORTRAIT, new RewardedVideoCallbackHandler() {...	                


Another capability of the SDK is to asychronously request a rewarded video ad. This gives you the opportunity to decide whether the video should actually play or if it should be discarded.
Hint: The average request-to-play time is around 1.5-3 seconds for video ads under good network conditions.
To request a video ad asynchonously, you can use the following code (note the different callback interface):
MainActivity.this.findViewById(R.id.button_get_extra_life_continue).setVisibility(View.GONE);
AyetSdk.showVideoAd(MainActivity.this, AyetSdk.FLAG_REWARDED | AyetSdk.FLAG_ASYNC, new RewardedVideoAsyncCallbackHandler() {
	@Override
	public void aborted() {
		// This is called when the user aborted / skipped a rewarded video ad
		Log.d(TAG , "AyetSdk.showRewardedVideoAdAsync::aborted()");
	}
	@Override
	public void completed(int amount) {
		// This is called when the user has watched a complete video ad - and should get an extra life in this example
		Log.d(TAG , "AyetSdk.showRewardedVideoAdAsync::completed() - GIVE EXTRA LIFE );
		MainActivity.this.giveExtraLifeAndContinue();
	}
	@Override
	public void nofill() {
		// This is called when either no video is available to watch, the user ran into your configured frequency caps, the AyetSdk has not been initialized or there were network/connectivity issues
		Log.d(TAG , "AyetSdk.showRewardedVideoAdAsync::nofill()");
	}
	@Override
	public void willBeShown() {
		// This is called after selecting a video, after "videoAd.showVideo()" has been called in "ready(...)" and right before the video activity is started to play it
		Log.d(TAG , "AyetSdk.showRewardedVideoAdAsync::willBeShown()");
	}
	@Override
	public void ready(final VideoAdInterstitial videoAd) {
		// This is called when a video has been selected and is ready to be shown. You have about 60 seconds to decide whether you want to play the video by calling "videoAd.showVideo();"
		// If showVideo isn't called, the video will be discarded and the video activity won't start.

		Log.d(TAG , "AyetSdk.showRewardedVideoAdAsync::ready()");

		// As an example, we're showing a "get extra life" button which is playing the rewarde video when clicked
		MainActivity.this.findViewById(R.id.button_get_extra_life_continue).setVisibility(View.VISIBLE);
		MainActivity.this.findViewById(R.id.button_get_extra_life_continue).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				videoAd.showVideo();
				v.setVisibility(View.GONE);
			}
		});
	}
});
                

8. Appendix I: Unmanaged Currency Handling / Conversion Callbacks


If you want to manually manage your users currencies on your own servers, you can configure a conversion callback url in our publisher dashboard.
To do so, navigate to Placements / Apps, edit your app placement and set the Callback Url to your server's postback url:


If this is the callback url your set for your app placement:
https://your-server.com/callback?network=ayetstudios&amount={currency_amount}&uid={uid}&device={advertising_id}&payout_usd={payout_usd}

A typical conversion callback sent by our server will look like this:
https://your-server.com/callback?network=ayetstudios&amount=360&uid=username&device=[GAID]&payout_usd=0.36
* Note: This assumes you set the user identifier to username in your AyetSdk.init(..) call, the currency conversion rate in your placement was 1000 per $1 and the user completed an offer with a $0.36 payout.

Important: Your server must always reply with an HTTP 200 status code to our postbacks. Otherwise we will resend the postback 12 times over a span of one hour before giving up.

Available Macros for Postback URLs:
{transaction_id}stringUnique transaction id - use for duplicate checks
{payout_usd}floatThe actual conversion payout in USD
{currency_amount}intThe amount of currency the user earned (taken from your offerwall currency configuration)
{uid}stringThe user identifier set in your app for this user when initializing the sdk
{user_id}integerOur internal id for this offerwall user
{placement_identifier}stringThe placement_identifier for which the conversion occured
{ip}stringConverting device's IP address if known, 0.0.0.0 otherwise
{offer_id}intOffer ID of the converting offer
{offer_name}stringName / title of the converting offer
{device_uuid}stringayeT-Studios internal device identificator
{device_make}stringDevice manufacturer
{device_model}stringDevice model
{advertising_id}stringDevice advertising id (GAID/IDFA) if known, otherwise empty
{sha1_android_id}stringDevice sha1 hashed android id if known, otherwise empty
{sha1_imei}stringDevice sha1 hashed imei if known, otherwise empty


If your want to restrict postbacks to our callback server IPs, please whitelist the following IPs and check back regularly for possible changes:
35.165.166.40
35.166.159.131
52.40.3.140	    
Last IP List Update: 2017-04-07


9. Appendix II: Proguard Rules / Release Builds


If you're going to use Proguard in your release build to obfuscate your application, make sure to add the following rules to your proguard-rules.pro files:
-keep class com.ayetstudios.publishersdk.messages.** {*;}
-keep public class com.ayetstudios.publishersdk.AyetSdk
-keepclassmembers class com.ayetstudios.publishersdk.AyetSdk {
   public *;
}
-keep public interface com.ayetstudios.publishersdk.interfaces.UserBalanceCallback { *; }
-keep public interface com.ayetstudios.publishersdk.interfaces.DeductUserBalanceCallback { *; }

-keep class com.ayetstudios.publishersdk.models.VastTagReqData { *; }
	                

Important: It's always highly recommended to test your release builds before publishing them on Google Play to verify that they behave as intended!


10. Appendix III: Multiple INSTALL_REFERRER Receivers


It's likely that you want to support multiple broadcast receivers for the INSTALL_REFERRER intent. An example would be Google Analytics, other analytics / statistics SDKs or third party tracking SDKs.
Since the Play Store will only fire one BroadcastReceiver in the manifest, the following example is showing how to use both Google Analytics and our Tracking SDK with a custom CombinedBroadcastReceiver class you can create in your app and extend for additional SDKs.

CombinedBroadcastReceiver.java:

public class CombinedBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Google Analytics
        new CampaignTrackingReceiver().onReceive(context, intent);

        // ayeT-Studios Publisher SDK
        new com.ayetstudios.publishersdk.TrackingReceiver().onReceive(context, intent);

        // add more third party broadcast receivers here...
    }
}	                



AndroidManifest.xml - the INSTALL_REFERRER receiver configuration

<receiver android:name="com.yourapplication.CombinedBroadcastReceiver" android:exported="true" android:enabled="true">
    <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
    </intent-filter>
</receiver>