Add to the /app/build.gradle file the repository where EMMA is located.
repositories {
maven { url 'https://repo.emma.io/emma' }
}
Add the dependency in the same build.gradle file.
dependencies {
implementation 'io.emma:eMMaSDK:4.13.+'
}
If you use proguard see the proguard documentation.
Finally, compile the project with gradle.
Session Key
EMMA Key
on the EMMA documentation pageThe SDK contains by default the following mandatory permissions. These permissions DO NOT have to be added in the AndroidManifest.xml
of the application, as they are added by the SDK itself:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
If you want to enable localization you have to add the following permissions to the AndroidManifest.xml
of your application:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
If the app is going to be uploaded to AppGallery or run on HMS compatible devices, it is necessary to add the connection with Huawei and the library to get a unique identifier for the device.
In the build.gradle of the project add the Huawei plugin.
buildscript {
repositories {
google()`
jcenter()
maven { url 'http://developer.huawei.com/repo/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.1'
classpath 'com.huawei.agconnect:agcp:1.6.2.300'
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
In the build gradle of the application, add the following dependency and apply the plugin to collect the configuration information of the app in Huawei.
dependencies {
// other dependencies
implementation 'com.huawei.hms:ads-identifier:3.4.62.300'
}
apply plugin: 'com.huawei.agconnect'
To obtain credentials you first need to create an account at developer.huawei.com and become a developer.
Once you have created an account you have to add an application in Huawei AppGallery Connect. The app is created in draft mode, to make the push integration is your client.
Once the app is created we can activate the Push Kit (it is optional, only if you want integrate push notifications) in the develop section. Inside Project Settings the information about the app will appear.
It is necessary to add the fingerprint of the certificate used for signing the app.
We download the agconnect-services.json and add it in /app. This way the HMS service will be able to authenticate the app.
Add the appId and appSecret in the app preferences section of the EMMA dashboard.
Finally, we compile the app and we can send push notifications to Huawei devices.
In your Application class, add the following:
import android.app.Application
import io.emma.android.EMMA
class ExampleApplication : Application() {
override fun onCreate() {
super.onCreate()
val configuration = EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.setDebugActive(BuildConfig.DEBUG)
.build()
EMMA.getInstance().startSession(configuration)
}
}
import android.app.Application;
import io.emma.android.EMMA;
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
EMMA.Configuration configuration = new EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.setDebugActive(BuildConfig.DEBUG)
.build();
EMMA.getInstance().startSession(configuration);
}
}
Screen sending is enabled by default in the EMMA SDK. To disable it use the following configuration.
import android.app.Application
import io.emma.android.EMMA
class ExampleApplication : Application() {
override fun onCreate() {
super.onCreate()
val configuration = EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.trackScreenEvents(false)
.setDebugActive(BuildConfig.DEBUG)
.build()
EMMA.getInstance().startSession(configuration)
}
}
Configure sub-domain for powlink
To support Powlink on Android, see the [support guide to configure Powlink].(https://docs.emma.io/es/adquisicion/apptracker#configurar-powlink-y-pwlnk-stu) on the EMMA dashboard
Knowing the subdomain that corresponds to your Powlinks, you must add a new activity to the AndroidManifest.xml
of your application as indicated below. This activity is the one that must also be used for the deeplink, as explained below.
<activity
android:name="io.emma.android.activities.EMMADeepLinkActivity"
android:noHistory="true"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="{YOUR_DEEPLINK_SCHEME}"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="subdomain.powlink.io"
android:scheme="https"/>
<data
android:host="shortsubdomain.pwlnk.io"
android:scheme="https"/>
</intent-filter>
</activity>
As explained below in the deeplink section, you must also add, inside the application tag, the metadata with the activity to be executed to process the powlink url.
<meta-data
android:name="io.emma.DEEPLINK_OPEN_ACTIVITY"
android:value="com.your.package.CustomDeeplinkActivity"/>
The Deeplink section shows how you can handle the received Powlinks or Deeplinks to process them and display the corresponding part of your application.
If you are using a tracker with a non-EMMA domain (.powlink.io or .pwlnk.io), it is necessary to add the domain when starting the library.
val configuration = EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.setDebugActive(BuildConfig.DEBUG)
.setShortPowlinkDomains("emma.link.mycompany.com")
.setPowlinkDomains("emma.link.mycompany.com")
.build()
EMMA.getInstance().startSession(configuration)
To differentiate a notification from our push system with respect to other systems, the payload sent by EMMA contains a flag called "eMMa".
EMMA offers a complete Push Notification delivery and reporting system that is easy to integrate using Firebase Cloud Messaging (FCM) on Android.
First get your own Sender ID and Server Key for FCM as specified in this [article] (https://docs.emma.io/es/comunicacion/mensajes-out-app/push-notifications#habilita-fcm-android-para-las-notificaciones-push) and set these parameters for the app in your EMMA account.
To integrate FCM into your app follow the steps below:
The following service must be added to AndroidManifest.xml:
<service
android:name="io.emma.android.push.EMMAFcmMessagingService"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
We add the following dependency to the build.gradle located in the root of the project:
buildscript {
// ...
dependencies {
// ...`
classpath 'com.google.gms:google-services:4.3.10' // google-services plugin`
}
}
allprojects {
// ...
repositories {
// ...
google() // Google's Maven repository`
}
}
In the build.gradle of the app we add the Firebase dependency:
apply plugin: 'com.android.application'
android {
// ...
}
dependencies {
//
// ...
implementation 'io.emma:eMMaSDK:4.12.+'
implementation 'com.google.firebase:firebase-messaging:23.1.0'
}
// ADD THIS AT THE BOTTOM
apply plugin: 'com.google.gms.google-services'
Start the push system under the Application login:
override fun onCreate() {
super.onCreate();
EMMA.Configuration configuration = new EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.setDebugActive(BuildConfig.DEBUG)
.build();
EMMA.getInstance().startSession(configuration);
val pushOpt = EMMAPushOptions.Builder(PushActivity::class.java, R.drawable.notification_icon)
.setNotificationColor(ContextCompat.getColor(this, R.color.yellow))
.setNotificationChannelName("Mi custom channel")
.build()
EMMA.getInstance().startPushSystem(configuration);
}
MyActivity.class: Activity you want to be opened when the Push is received
R.drawable.icon: (Optional) The resource id of the image you want to display with the Push notification. If no icon is specified, the Push will use the app icon.
customDialog: (Optional) Set this to ensure that you want to use your Custom Dialog.
Add the Activity's onNewIntent() method calling EMMA.onNewNotification(), which will check if the user has received a notification when the app is open.
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent);
EMMA.getInstance().onNewNotification(this, intent, true);
}
The boolean that has as parameter the onNewNotification method checks that the push contains Rich Push Url in case it is set to true.
To check the richPushUrl when the app is opened from the notification, add in the push activity the following:
class ExampleActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
EMMA.getInstance().checkForRichPushUrl();
}
}
The checkForRichPushUrl may also be used anywhere in the app if preferred.
If your app is based on a WebView, you need to add the checkForRichPushUrl in the following method:
webView.webViewClient = object : WebViewClient() {
...
override fun onPageFinished(view: WebView, url: String) {
EMMA.getInstance().checkForRichPushUrl();
}
}
Optionally, if you want to control what you receive from a Push, your Activity must implement the EMMANotificationInterface interface and the onPushOpen method that will be called when the user opens the notification.
class ExampleActivity : Activity(), EMMAInAppMessageInterface {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
EMMA.getInstance().getNotificationInfo();
}
override fun onPushOpen(pushCampaign: EMMAPushCampaign) {
//Do whatever you want with push campaign
}
}
To disable notifications from a device, use EMMA.getInstance().unregisterPushService() and make sure not to call EMMA.getInstance().startPushSystem(...) again.
You can use shortcuts if you don't need all parameters. You can find them here.
You can select the color you want in push notifications by adding the setNotificationColor to the push options:
val pushOpt = EMMAPushOptions.Builder(PushActivity::class.java, R.drawable.notification_icon)
.setNotificationColor(ContextCompat.getColor(this, R.color.yellow))
.build()
EMMA.getInstance().startPushSystem(configuration);
SDK version 2.5.5 or higher is required.
To use custom sounds in the notifications you send with EMMA, you have to add the sound files you want to the raw folder of your app resources (res folder). Remember to use the same file names for the sounds in iOS and Android.
You can redirect push notification openings to a section in your app. To do this you should use a structure like this:
scheme://host/page1/page2/page3...
Version 4.2 brings changes concerning the management of the deep link. To integrate it follow the steps below:
Add the following activity in the AndroidManifest.xml :
<activity
android:name="io.emma.android.activities.EMMADeepLinkActivity" android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="YOUR_SCHEME"`
android:host="YOUR_HOST"/>
</intent-filter>
</activity>
Add the activity to be launched, in the form of meta-data inside the tag in AndroidManifest.xml. This activity will be triggered when the SDK executes a deeplink:
<meta-data
android:name="io.emma.DEEPLINK_OPEN_ACTIVITY"
android:value="com.your.package.CustomDeeplinkActivity"/>
Remember that in case it is an activity that can be found open in the app when a deeplink is executed, it has to be declared in the AndroidManifest.xml as singleTask:
<activity`
android:name=".activities.MainActivity"
android:launchMode="singleTask"/>
In this case, if the activity is on the stack when the deeplink is executed, the intent with the deeplink information will reach the activity's onNewIntent method. In case of not having the "launchMode" as singleTask it causes the activity to be instantiated again, which produces duplications.
For the deeplink that is entered in the Rich Push URL field (on the EMMA website) to be executed correctly, it is important to add the following method in the activity that is opened by the push or some other that is consequent to it, but that is executed when the app is opened from the notification:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
EMMA.getInstance().checkForRichPush();
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent);
EMMA.getInstance().onNewNotification(intent, true);
}
The checkForRichPush and onNewNotification methods check the Rich Push field sent in the notification payload and perform the appropriate actions. In the case of a deeplink they will execute it by opening the activity defined in the AndroidManifest.xml metadata.
Define the behavior of the activity that has to open the deeplink. In this case CustomDeepLinkActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view);
if (intent != null && intent.data != null ) {
processDeepLink(intent.data);
}
finish();
}
private fun processDeepLink(uri: Uri) {
if (uri.host.equals("home")) {
goHome();
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent);
if (intent != null && intent.data != null ) {
processDeepLink(intent.data);
}
}
EMMA gives the possibility to integrate push notifications outside its own service.
class CustomService: FirebaseMessagingService() {
private fun isPushFromEMMA(remoteMessage: RemoteMessage): Boolean {
return remoteMessage.data["eMMa"] == "1"
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
if (isPushFromEMMA(remoteMessage)) {
EMMAPushNotificationsManager.handleNotification(applicationContext, remoteMessage.data)
}
}
override fun onNewToken(token: String) {
EMMAPushNotificationsManager.refreshToken(applicationContext, token, EMMAPushType.FCM)
}
}
On version 4.10.x, the functionality of adding buttons with actions in notifications has been developed. To add this functionality to Android, you simply have to have the SDK updated to this version.
For the configuration in the interface consult here.
On May 19, 2019, Google decided to terminate with Huawei those businesses that require hardware and software transfer, except those covered by open source licenses. This means that devices manufactured after this date will not have Google services such as the Play Store, although they will have the equivalent, the Huawei App Gallery.
From EMMA, we have modified our SDK to adapt it to the Huawei App Store. With the aim of measuring attribution as well as allowing Push notifications to be sent via their service.
The minimum version of the SDK available to make the Huawei integration is version 4.7.0. If you have an earlier version of the SDK, you will need to update it for everything to work properly.
To perform integration you have to follow the following steps:
The first thing we need to do is to add the dependencies to the build.gradle of the project.
buildscript {
repositories {
google()`
jcenter()
maven { url 'http://developer.huawei.com/repo/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.1'
classpath 'com.huawei.agconnect:agcp:1.6.2.300'
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
Next we add the HMS dependencies to the application. The ads-identifier dependency allows to get the advertisement identifier used in Huawei. The push dependency allows the use of the HMS service for push notifications.
build.gradle
dependencies {
// other dependencies
implementation 'com.huawei.hms:ads-identifier:3.4.62.300'
implementation 'com.huawei.hms:push:6.10.0.300'
}
apply plugin: 'com.huawei.agconnect'
The HMS service integration is compatible with the FCM integration in the EMMA SDK. The minimum Android version supported for HMS integration is Android 19.
The following service must be added to AndroidManifest.xml:.
<service
android:name="io.emma.android.push.EMMAHmsMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
To obtain the credentials go to the following section here
Finally, we compile the app and we can now send push notifications to Huawei devices.
With EMMA you can perform a complete integration of the SDK that allows you to know the location of your users, how they register in your App, how many transactions they perform and even their own characteristics. That is, all the information about your users that you will get in the Behavior section.
The EMMA platform differentiates between two types of events. Those that the platform includes by default and the Custom events that you want to integrate according to the structure of your application.
https://docs.emma.io/es/primeros-pasos/eventos#eventos-por-defecto
Documentation of default events: *Documentation of default events:*Documentation of default events
https://docs.emma.io/es/primeros-pasos/eventos#eventos-personalizados
Example to send an application's own event:
val eventRequest = EMMAEventRequest("f983d4bef8fc44dad43a1bb30dde9e3c")
//Optional: custom attributes
eventRequest.attributes = attributes
//Optional: request status listener
eventRequest.requestListener = requestListener
//Optional: cumtom id for request delegate
eventRequest.customId = customId
EMMA.getInstance().trackEvent(eventRequest)
EMMAEventRequest eventRequest = new EMMAEventRequest("f983d4bef8fc44dad43a1bb30dde9e3c");
//Optional: custom attributes
eventRequest.setAttributes(attributes);
//Optional: request status delegate
eventRequest.setRequestDelegate(requestDelegate);
//Optional: cumtom id for request delegate
eventRequest.setCustomId(customId);
EMMA.getInstance().trackEvent(eventRequest);
In EMMA we can enrich the user profile with information stored by Key / Value which we call user tags.
To send this information we should implement the trackExtraUserInfo(java.util.Map<java.lang.String,java.lang.String> info) method.
If your application has location permissions, EMMA can store that information in the user's profile.
If you do not want to record the user's information, you must implement the disableTrackingLocation() method before executing the startSession
call.
We can retrieve the internal EMMA identifier with the getUserID() method.
If we need to retrieve the user's profile from the application we will use the getUserInfo() method.
After the attribution process, EMMA makes the user's attribution information available to the SDK.
To get the attribution information we will use the getInstallAttributionInfo(io.emma.android.interfaces.EMMAInstallAttributionInterface) method.
See the [description of attribution fields](/en/reference/user-info-fields#description-of-user-attribution-fields](/en/reference/user-info-fields#description-of-user-attribution-fields) for available information.
If you use proguard or a compatible alternative, below is an example of the contents of the progruard-rules.pro
rules file. You may have to modify other rules depending on the application.
# EMMA SDK
-keep class io.emma.android.** { *; }
# Rules for play services ads identifier
-keep class com.google.android.gms.common.ConnectionResult {
int SUCCESS;
}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient {
com.google.android.gms.ads.identifier.AdvertisingIdClient$Info getAdvertisingIdInfo(android.content.Context);
}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info {
java.lang.String getId();
boolean isLimitAdTrackingEnabled();
}
# Rule for google play referrer
-keep public class com.android.installreferrer.** { *; }
# Rules for okhttp3
-keepattributes Signature
-keepattributes Annotation
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
-dontwarn okio.**
# Rules for retrofit2
-keepattributes Signature, InnerClasses, EnclosingMethod
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn javax.annotation.**
-dontwarn kotlin.Unit
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
# Firebase for push
-keep class com.google.firebase.** { *; }
# Rules for glide (used to display images by sdk)
-keep class com.bumptech.glide.** { *; }
-dontwarn com.bumptech.glide.**
# Rules for Huawei hms push and odid identifier (optional)
#-keepattributes *Annotation*
#-keepattributes Exceptions
#-keepattributes InnerClasses
#-keepattributes Signature
#-keepattributes SourceFile,LineNumberTable
#-keep class com.hianalytics.android.** {*;}
#-keep class com.huawei.updatesdk.** {*;}
#-keep class com.huawei.hms.** {*;}
# Rules for Huawei ads-identifier and ads referrer (optional)
#-keep class com.huawei.hms.ads.** { *; }
#-keep interface com.huawei.hms.ads.** { *; }
In some cases, it is necessary to change the EMMA API url (e.g. proxies), for this you have to add the following just before the startSession(...)
method:
val configuration = EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.setWebServiceUrl("https://www.your_proxy_url.com/")
.setDebugActive(BuildConfig.DEBUG)
.build()
EMMA.Configuration configuration = new EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.setDebugActive(BuildConfig.DEBUG)
.setWebserviceUrl("https://www.your_proxy_url.com/")
.build();
Messaging includes 7 different communication formats that you can integrate to impact your users:
EMMA NativeAd allows you to get the information of a NativeAd corresponding to a template that has been defined and configured in the EMMA platform.
class NativeAdsActivity: BaseActivity(),
EMMAInAppMessageInterface,
EMMABatchNativeAdInterface,
EMMANativeAdInterface {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
fun getNativeAd(templateId: String) {
val nativeAdRequest = EMMANativeAdRequest()
nativeAdRequest.templateId = templateId
EMMA.getInstance().getInAppMessage(nativeAdRequest, this)
}
fun getNativeAdBatch(templateId: String) {
val nativeAdRequest = EMMANativeAdRequest()
nativeAdRequest.templateId = templateId
nativeAdRequest.isBatch = true
EMMA.getInstance().getInAppMessage(nativeAdRequest, this)
}
override fun onBatchReceived(nativeAds: MutableList<EMMANativeAd>) {
nativeAds.forEach { nativeAd ->
nativeAd.tag?.let { tag ->
print("Received batch nativead with tag: $tag")
}
}
}
override fun onReceived(nativeAd: EMMANativeAd) {
val content = nativeAd.nativeAdContent
val title = content["title"]
if (title != null) {
print("Received NativeAd with Title: $title")
EMMA.getInstance().sendInAppImpression(CommunicationTypes.NATIVE_AD, nativeAd)
}
}
fun openNativeAd(nativeAd: EMMANativeAd) {
EMMA.getInstance().openNativeAd(nativeAd)
}
fun sendNativeAdClick(nativeAd: EMMANativeAd) {
EMMA.getInstance().sendInAppClick(CommunicationTypes.NATIVE_AD, nativeAd)
}
override fun onShown(campaign: EMMACampaign) {
print("Invocadoo método onShown")
}
override fun onHide(campaign: EMMACampaign) {
print("Invocadoo método onHide")
}
override fun onClose(campaign: EMMACampaign) {
print("Invocadoo método onClose")
}
}
We will obtain all the information of the NativeAd available to the user regarding the templateId, according to the conditions that have been configured in the EMMA platform.
OnReceived:EMMANativeAd* nativeAd is called in case there is a NativeAd corresponding to the template with identifier "templateId".
EMMANativeAd contains all the fields configured in EMMA for this NativeAd template, to obtain them the following method will be used:
Once all the required fields are obtained, you can now create the view to paint this NativeAd on screen according to the design you want to apply to it. Once the NativeAd is painted on the screen, it is necessary to call this method to obtain the printouts in the reporting:
EMMA.getInstance().sendInAppImpression(CommunicationTypes.NATIVE_AD, nativeAd)
To obtain a unique Native Ad you have to use the method getInAppMessage passing it an instance of EMMANativeAdRequest with the specific templateId that you want to use. In the case of having several Native Ad under the same templateId with this method you get the last one created.
fun getNativeAd(templateId: String) {
val nativeAdRequest = EMMANativeAdRequest()
nativeAdRequest.templateId = templateId
EMMA.getInstance().getInAppMessage(nativeAdRequest, this)
}
Method used to obtain all the active Native Ads under the same templateId.
fun getNativeAdBatch(templateId: String) {
val nativeAdRequest = EMMANativeAdRequest()
nativeAdRequest.templateId = templateId
nativeAdRequest.isBatch = true
EMMA.getInstance().getInAppMessage(nativeAdRequest, this)
}
The SDK provides a method to perform the opening of a Native Ad, this method is set as a CTA when you click or perform some action on the Native Ad. Internally this method launches an inapp WebView or opens the browser with the CTA configured in the Dashboard and then traces the click.
fun openNativeAd(nativeAd: EMMANativeAd) {
EMMA.getInstance().openNativeAd(nativeAd)
}
Alternatively, if this method is not used, the click can be sent by calling the method:
EMMA.getInstance().sendInAppClick(nativeAd)
The StartView is a communication format that allows you to display HTML content, hosted at a URL, in a full-screen WebView.
fun getStartView() {
val startViewRequest = EMMAInAppRequest(EMMACampaign.Type.STARTVIEW)
EMMA.getInstance().getInAppMessage(startViewRequest)
}
The AdBall is a small circular view that displays an image. This view can be dragged all over the screen and removed from it at any time, it contains a CTA which is a URL with HTML content that launches a WebView when clicked.
fun getAdBall() {
val adBallRequest = EMMAInAppRequest(EMMACampaign.Type.ADBALL)
EMMA.getInstance().getInAppMessage(adBallRequest)
}
The banner is a communication format that allows to adapt an image or GIF in banner format within an application screen. This banner can be displayed on the screen where it is displayed or at the bottom of the screen. The banner contains a configurable CTA in the EMMA Dashboard and it can be a deeplink or an https url, in the case of the second option when clicking it opens a WebView with the content of the url.
It is recommended to make the call after all the elements of the screen are loaded.
fun getBanner() {
val bannerRequest = EMMAInAppRequest(EMMACampaign.Type.BANNER)
EMMA.getInstance().getInAppMessage(bannerRequest);
}
The strip allows you to display a banner at the top of the device's screen with a text that scrolls as a carousel, variables such as the duration of the rotation or the display time are configurable from the Dashboard.
fun getStrip() {
val stripRequest = EMMAInAppRequest(EMMACampaign.Type.STRIP)
EMMA.getInstance().getInAppMessage(stripRequest);
}
EMMA Coupons allows you to obtain, verify and redeem coupons that have been defined and configured on the EMMA platform.
class CouponsActivity: BaseActivity(), EMMACouponsInterface {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
EMMA.getInstance().addCouponsCallback(this)
getCoupons()
}
private fun getCoupons() {
EMMA.getInstance().getInAppMessage(EMMAInAppRequest(EMMACampaign.Type.COUPON))
}
private fun getSingleCoupon() {
val couponsRequest = EMMAInAppRequest(EMMACampaign.Type.COUPON)
couponsRequest.inAppMessageId = "<COUPON_ID>"
EMMA.getInstance().getInAppMessage(couponsRequest)
}
private fun redeemCoupon() {
val redeemCouponRequest = EMMAInAppRequest(EMMACampaign.Type.REDEEM_COUPON)
redeemCouponRequest.inAppMessageId = "<COUPON_ID>"
EMMA.getInstance().getInAppMessage(redeemCouponRequest)
}
private fun cancelCoupon() {
val cancelCouponRequest = EMMAInAppRequest(EMMACampaign.Type.CANCEL_COUPON)
cancelCouponRequest.inAppMessageId = "<COUPON_ID>"
EMMA.getInstance().getInAppMessage(cancelCouponRequest)
}
private fun couponValidRedeems() {
val couponValidRedeems = EMMAInAppRequest(EMMACampaign.Type.COUPON_VALID_REDEEMS)
couponValidRedeems.inAppMessageId = "<COUPON_ID>"
EMMA.getInstance().getInAppMessage(couponValidRedeems)
}
override fun onCouponsReceived(coupons: List<EMMACoupon>) {
coupons.let {
// Show coupons
coupons.forEach { coupon ->
EMMA.getInstance().sendInAppImpression(CommunicationTypes.COUPON, coupon)
}
}
}
override fun onCouponsFailure() {
print("An error has occurred obtaining coupons")
}
override fun onCouponRedemption(success: Boolean) {
print("Coupon redemption success: $success")
}
override fun onCouponCancelled(success: Boolean) {
print("Coupon cancelled success: $success")
}
override fun onCouponValidRedeemsReceived(numRedeems: Int) {
print("Coupon redeems: $numRedeems")
}
}
With this call, we will obtain all the information of the coupons available to the user, according to the conditions that have been configured in the EMMA platform.
private fun getCoupons() {
EMMA.getInstance().getInAppMessage(EMMAInAppRequest(EMMACampaign.Type.COUPON))
}
A list of existing coupons will be returned, listing first the automatic coupons sorted from most recent to oldest, and then the classic coupons will be listed, also sorted from most recent to oldest.
EMMACouponsInterface.onCouponsReceivedis called in case the user has coupons available to redeem, or
EMMACouponsInterface.onCouponsFailure` if the user has no coupons available. EMMACoupon contains all the information related to the coupon: id (EMMA's internal identifier), code, maximum number of redemptions, number of times redeemed, title, description, image...
If you want to send to EMMA the information about when the coupon has been clicked or when it is displayed on the screen, you have to add the following methods when both actions are performed in the app:
EMMA.getInstance().sendInAppImpression(CommunicationTypes.COUPON, couponCampaign);
EMMA.getInstance().sendInAppClick(CommunicationTypes.COUPON, couponCampaign);
private fun cancelCoupon() {
val cancelCouponRequest = EMMAInAppRequest(EMMACampaign.Type.CANCEL_COUPON)
cancelCouponRequest.inAppMessageId = "<COUPON_ID>"
EMMA.getInstance().getInAppMessage(cancelCouponRequest)
}
With this call you can cancel the redemption of a previously made coupon.
The parameter couponId must be the EMMA internal identifier of a coupon identifier that can be obtained from a call to getCoupons made previously.
The EMMACouponsInterface.onCouponCancelled
is called, where success indicates whether the coupon has been cancelled.
As of version 4.9.0 the possibility to add in-app plugins to the SDK has been added. The in-app plugins work through Native Ad technology.
You can create your own communication format and turn it into an in-app plugin, for this it is necessary that the main class of the new format extends the abstract class EMMAInAppPlugin, this class forces to override two methods:
class CustomInAppPlugin: EMMAInAppPlugin() {
override fun getId(): String = "emma-plugin-custom"
override fun show(context: Activity?, nativeAd: EMMANativeAd) {
// Process data
}
override fun dismiss() {
}
The show() method is the main method as it is the one that launches the SDK when it receives the Native Ad
corresponding to the plugin, the SDK passes to the plugin as context the current activity that is visible in the app and the Native Ad with the content according to the template marked as plugin in the Dashboard. With these parameters you can create any communication format adapted to the content of the Native Ad.
The dismiss() method is to hide the plugin automatically, at the moment the SDK does not have this functionality built in, it leaves the control of hiding to the plugin itself.
The getId() method returns the identifier of the plugin that corresponds to the templateId generated in the template.
The EMMAInAppPlugin class contains several static methods such as sendInAppImpression and sendInAppClick, as in Native Ad, you can send these actions. You can also invoke the inappMessageListener(s) with the invokeShownListeners, invokeCloseListeners and invokeHideListeners methods.
Puedes consultar el ejemplo de plugin aquí
To integrate a plugin it is necessary to add it in the sdk after the login, for this it is necessary to use the addInAppPlugin method.
class App: Application {
override fun onCreate() {
super.onCreate()
....
EMMA.getInstance().startSession(configuration)
EMMA.getInstance().addInAppPlugins(CustomPlugin())
}
}
Once the sdk has the plugin you simply have to call it in the part of the app where it is required as if it were a Native Ad.
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val request = EMMANativeAdRequest()
request.templateId = "emma-plugin-custom"
EMMA.getInstance().getInAppMessage(request)
}
}
With this functionality we can limit the urls that the EMMA SDK will open, so that in the In-App communications, only the content that starts with one of the urls that we have
In-App communications, only the content that begins with one of the urls that we have indicated in the whitelist will be shown in a Webview.
If we do not indicate any url in the whitelist, any url is allowed. This functionality would affect Push (Rich URL), Banners, StartViews and AdBalls. Communications (Banners, StartViews and AdBalls) that can load external content to the app through a Webview and for Banners and AdBalls could load external images that would also be controlled by the whitelist.
For a Push with Rich URL, if it does not comply, the corresponding Webview would not be opened, but the push does reach the application, note that if instead of a url a deeplink is used, the deeplink scheme must be added to the whitelist to be able to open it.
fun enableWhitelist() {
EMMA.getInstance().whitelist = mutableListOf("https://mydomain.com", "https://mydomain2.com")
}
If my whitelist is "http://mydomain.com".
Upload to EMMA dashboard a Banner with Target URL https://mydomain.com
The Banner will not be displayed, we should add https://mydomain.com to the whitelist.
Configure a StartView with StartView URL http://www.mydomain.com in the EMMA dashboard.
The StartView will not be displayed, we should add http://www.mydomain.com to the whitelist.
Configure in the EMMA dashboard a Banner with Target URL http://mydomain.com/my/url and SmartPhone Banner URL http://subdomain.mydomain.com/my/image
The Banner will not be displayed, the url of the image does not comply with the whitelist, we should add to the whitelist http://subdomain.mydomain.com
We upload a Banner with Target URL http://mydomain.com/my/url/ to the EMMA dashboard.
The Banner will be displayed because the url entered in the Target URL field starts with the same protocol and domain as the whitelist url.
We configure in the EMMA dashboard a StartView with StartView URL http://mydomain.com/mypage.html¶m=value
The StartView will be displayed because the url entered in the StartView URL field starts with the same protocol and domain as the whitelist url.
EMMA allows you to disable tracking for those users who express this wish.
This method is the best way to adapt to the new RGPD (General Data Protection Regulation).
The user's communication to express this opt-out option must be handled by the app by making a call to the following method:
public fun disableUserTracking(deleteUserData: Bool) {
/*
disableUserTracking() shuts down all communication with EMMA servers
If deleteUserData is true; EMMA will remove this device data from
their servers. This is a unrecoverable action.
*/
EMMA.getInstance().disableUserTracking(deleteUserData)
}
public void disableUserTracking(boolean deleteUserData) {
/*
disableUserTracking() shuts down all communication with EMMA servers
If deleteUserData is true; EMMA will remove this device data from
their servers. This is a unrecoverable action.
*/
EMMA.getInstance().disableUserTracking(deleteUserData)
}
In case you want to re-enable the user's communications, you can use this other method:
public func enableUserTracking() {
EMMA.getInstance().enableUserTracking()
}
- public void enableUserTracking {
EMMA.getInstance().enableUserTracking()
}
For all apps that are within the "Designed for Famalies" program, they need to meet a series of requirements regarding the information to be shared, for this EMMA has enabled a property at the start session to ensure compliance with this policy.
import android.app.Application
import io.emma.android.EMMA
class ExampleApplication : Application() {
override fun onCreate() {
super.onCreate()
val configuration = EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.setDebugActive(BuildConfig.DEBUG)
.setFamiliesPolicyTreatment(true)
.build()
EMMA.getInstance().startSession(configuration)
}
}
import android.app.Application;
import io.emma.android.EMMA;
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
EMMA.Configuration configuration = new EMMA.Configuration.Builder(this)
.setSessionKey("example0ikl98")
.setFamiliesPolicyTreatment(true)
.setDebugActive(BuildConfig.DEBUG)
.build();
EMMA.getInstance().startSession(configuration);
}
}
In addition, it is also important to disable the permission to collect the Google Advertising ID in the AndroidManifest.
<uses-permission android:name="com.google.android.gms.permission.AD_ID"
tools:node="remove"/>