Android - Using The SDK
Android - Using The SDK
Product Manual
Current release: 11/7/2018
2 Table of content
1 Table of content
2 Intro
The purpose of this document is to detail how to install the SDK into your app and how
to easily start using it.
• For more detailed implementation of the SDK please refer to the “Android -
MobileSDK Reference.pdf” document.
• If you don’t have any yet, go to https://console.firebase.google.com/ and sign in with a Google
account.
• If you already have a project on Google Developer Console, click on “Import Google Project”,
otherwise click on “Create new project” and follow instructions.
• Click on “Add Firebase to your Android app” and enter your package name.
• Download the JSON file, put it in your app and update the gradle files as instructed on Firebase.
Including the SDK in your project 5
• Click on the tab “Cloud Messaging”, you will see the Server key and the Sender ID.
• Note the Server key, you will have to give it to the Selligent platform (the Sender ID is not needed
by the SDK anymore as long as you don’t use the deprecated method “registerDevice”).
Make sure that you have jcenter() in the list of repositories in the build.gradle file at
root level.
com.google.firebase:firebase-messaging
- The version of Firebase must be at least 10.2.1 in order to be compatible with Android O. It is
recommended to use the latest one available.
- If you followed the instructions given to you by Firebase (cf. Creating a Google application) to
update your gradle files, you should have the following:
o In the build.gradle file at project level:
• dependencies {
classpath 'com.google.gms:google-services:X.Y.Z'
}
o In the build.gradle file at app level, at the bottom:
• apply plugin: 'com.google.gms.google-services'
• If you plan on sending Map type push, you need a dependency to play-services-maps.
com.google.android.gms:play-services-maps
• GSON
com.google.code.gson:gson
How to use the SDK 7
• CardView
com.android.support:cardview-v7
• FirebaseJobDispatcher
This dependency is mandatory if you are going to send encrypted push to your app.
com.firebase:firebase-jobdispatcher
• MetadataXTractor
If you plan on sending Push or In-App messages containing “Response” type buttons, you have to
add the following third party library:
com.drewnoakes:metadata-extractor
• PlotProject
If you want to use geolocation, you will need a dependency to the PlotProject library:
com.plotprojects:plot-android:2.5.1
For Gradle to find that dependency, you must add a reference to the Maven Plot repository. In the
list of repositories in your top build.gradle file, add
allprojects {
repositories {
…
maven {
url 'https://maven-repo.plotprojects.com'
}
}
}
5.1.2 Start
To start the SDK, in your class extending Application, use the following:
SMManager.getInstance().start(settings, this);
8 How to use the SDK
WebServiceUrl must be the URL of the Selligent web service that will be called. It is
given by Selligent.
GoogleApplicationId is deprecated, you can leave it to null as long as you use the
JSON file given by Firebase.
ClientId is the public key allowing the connection to the web service.
PrivateKey is the private key allowing the connection to the web service.
Ex.:
SMSettings settings = new SMSettings();
settings.WebServiceUrl = "https://www.some.web.service.com";
settings.ClientId = "SomeClientId";
settings.PrivateKey = "SomePrivateKey";
SMManager.getInstance().start(settings, this);
SMManager.DEBUG = true;
Setting this to true will add the SDK logs to the logcat (it is better to do that before
calling the start method in order to see everything logged when the SDK starts).
How to use the SDK 9
or in a dedicated Activity, depending of the type of the push (Map, Image, HTML and
URL open in a dedicated Activity).
5.2.1 Libraries
If you plan on sending push notifications containing “Response” type buttons, you have
to add the following third party library in your dependencies:
com.drewnoakes:metadata-extractor:2.9.1
Only one of the two is needed. Coarse location is less precise than fine location. Note
that if you do not add any, the map will still be displayed, just not the user’s location.
10 How to use the SDK
If you plan on sending push that include a “Response with picture” type button, you
must add the following permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This is needed to access the pictures on the device and call the photo app. If it is not
present in the manifest, the user will not be able do anything and a message “Not
enough permission” will appear instead (this message can be changed, cf. Translations).
Warning: do NOT use “READ_EXTERNAL_STORAGE” instead of
“WRITE_EXTERNAL_STORAGE”, this would result in the app crashing when the user
tries to access the camera or the gallery.
[…]
SMManager.getInstance().registerDevice(this);
}
This registration is asynchronous and is executed only once after the application
started (it will be executed again the next time you start the app after killing it).
If you use the JSON file method, then this call is useless, everything will be done in
the background.
First, you will need to add a member to your class with a type SMForegroundGcmBroadcastReceiver.
SMForegroundGcmBroadcastReceiver receiver;
Then, update the onCreate, onStart, onStop and onNewIntent events like this:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
[…]
SMManager.getInstance().checkAndDisplayMessage(getIntent(), this);
}
@Override
protected void onStart()
{
super.onStart();
[…]
How to use the SDK 11
if (receiver == null)
{
receiver = new SMForegroundGcmBroadcastReceiver(this);
}
registerReceiver(receiver, receiver.getIntentFilter());
}
@Override
protected void onStop()
{
super.onStop();
[…]
unregisterReceiver(receiver);
}
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
SMManager.getInstance().checkAndDisplayMessage(intent, this);
}
5.2.5 Customization
If the app is in background when a push is received, an icon will appear in the status bar and a notification
will be added to the Notification drawer. Clicking on it will call a specific Activity which will display the
message. Both can be customized.
5.2.5.1 Setting a specific icon
To customize that icon, call these methods after starting the SDK in your Application class:
SMManager.getInstance().setNotificationSmallIcon(R.drawable.some_icon);
This sets the small icon that will be used for the notifications in the notification bar. If
not set, the default icon of the SDK will be used (the head of the Android robot).
SMManager.getInstance().setNotificationLargeIcon(R.drawable.some_large_icon);
This sets the large icon that will be used for the notifications. If not set, no large icon
will be specified to Android, so the small one will be used.
<application
…>
…
<activity
android:name="com.selligent.sdk.NotificationActivity"
12 How to use the SDK
android:parentActivityName=".MainActivity">
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"></meta-data>
</activity>
</application>
You can also set any Activity of your app to be called instead (in which case, no need to add the previous
code to your manifest).
PS: the background and text colors will be the one defined in your theme.
This is a default layout made to have a “Material” look. It is entirely customizable. Its
definition is in the file “styles.xml”. Here is its content:
<style name="Selligent.Dialog.Container">
<item name="android:paddingLeft">0dp</item>
<item name="android:paddingRight">0dp</item>
<item name="android:paddingTop">0dp</item>
<item name="android:paddingBottom">0dp</item>
</style>
<style name="Selligent.Dialog.Title">
<item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item>
<item name="android:layout_marginLeft">24dp</item>
<item name="android:layout_marginRight">24dp</item>
<item name="android:layout_marginTop">24dp</item>
<item name="android:layout_marginBottom">0dp</item>
<item name="android:textSize">20sp</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
How to use the SDK 13
<item name="android:typeface">sans</item>
<item name="android:textStyle">bold</item>
<item name="android:shadowRadius">0</item>
<item name="android:gravity">start</item>
</style>
<style name="Selligent.Dialog.UpperDivider">
<item name="android:layout_height">0dp</item>
<item name="android:visibility">gone</item>
</style>
<style name="Selligent.Dialog.BodyScrollView">
<item name="android:clipToPadding">false</item>
<item name="android:layout_marginTop">20dp</item>
<item name="android:layout_marginLeft">24dp</item>
<item name="android:layout_marginRight">24dp</item>
<item name="android:layout_marginBottom">24dp</item>
</style>
<style name="Selligent.Dialog.Body">
<item name="android:textSize">16sp</item>
<item name="android:typeface">sans</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:maxLines">10</item>
</style>
<style name="Selligent.Dialog.LowerDivider">
<item name="android:layout_height">0dp</item>
</style>
<style name="Selligent.Dialog.ButtonScrollView">
</style>
<style name="Selligent.Dialog.ButtonContainer">
<item name="android:gravity">end</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
</style>
<style name="Selligent.Dialog.ButtonRow">
<item name="android:layout_width">wrap_content</item>
</style>
<style name="Selligent.Dialog.Button">
<item name="android:layout_height">36dp</item>
<item name="android:minWidth">64dp</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:radius">2dp</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:textSize">14sp</item>
<item name="android:typeface">sans</item>
<item name="android:textAllCaps">true</item>
<item name="android:textColor">#ff80cbc4</item>
<item name="android:background">?android:attr/selectableItemBackground</item>
</style>
To customize it, in your own file “styles.xml”, override the styles you want to modify.
Note that you have to copy the whole content of those styles, not only the items you
want to change, otherwise the others will be lost.
For example, if you simply want to change the text color of a button to red, you still
have to add in your file the whole style:
<style name="Selligent.Dialog.Button">
<item name="android:layout_height">36dp</item>
<item name="android:minWidth">64dp</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:radius">2dp</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:textSize">14sp</item>
14 How to use the SDK
<item name="android:typeface">sans</item>
<item name="android:textAllCaps">true</item>
<item name="android:textColor">#ff0000</item>
<item name="android:background">?android:attr/selectableItemBackground</item>
</style>
5.2.6.2 Activities
Some other type of messages (like Map, HTML, Response, etc.) are displayed in their own activity, not in a
dialog. Those activities extend AppCompatActivity and, therefore, need an AppCompat theme. So, in
order to avoid any crash when displaying them, we force our own AppCompat theme: Theme.SMTheme.
It has for parent Theme.AppCompat.Light. You might want to override it to reflect your own layout.
To do so, simply define that theme in your app and use as parent the appropriate AppCompat theme.
Examples:
• If you use Theme.Holo.Light, define Theme.SMTheme like this (in styles.xml):
<item name="colorPrimary">@color/yourPrimaryColor</item>
<item name="android:textColorPrimary">@color/yourTextColor</item>
</style>
(cf. https://developer.android.com/training/material/theme.html)
Note: avoid using a “NoActionBar” theme as parent because it would hide the toolbar, rendering the
“Response push/In-App message” functionality useless (the icon used to send the response would not be
displayed).
5.2.7.1 Broadcast
You can listen to SMManager.BROADCAST_EVENT_RECEIVED_GCM_TOKEN (its value
is “SMReceivedGCMToken”). This broadcast is sent after reception of the token from
FCM and only if it is different from the one already stored.
It’s a local broadcast and, therefore, must be listened to using a
LocalBroadcastManager.
The value of the token can be retrieved from the intent received by using
SMManager.BROADCAST_DATA_GCM_TOKEN (its value is “SMDataGCMToken”).
switch (action)
{
case SMManager.BROADCAST_EVENT_RECEIVED_GCM_TOKEN:
String gcmToken =
intent.getStringExtra(SMManager.BROADCAST_DATA_GCM_TOKEN);
//Do some stuff
break;
}
}
}
5.2.7.2 SMManager.getInstance().getGCMToken
This method will return the token stored by the SDK.
Note that, as the processing to register to FCM is asynchronous, it is possible that the
value returned is either empty or not up-to-date if the registration is not finished yet
when the call is made.
16 How to use the SDK
SMManager.getInstance().enableNotifications();
5.2.9.2 Event
When displayed, the message of a push can contain buttons. One type of button can
send a broadcast containing a specific value, in order for you to execute some code
when you receive it. This broadcast is sent locally using LocalBroadcastManager. In
order to listen to it, you need to add a BroadcastReceiver to your app, specify the
action (the aforementioned value) and register it using LocalBroadcastManager.
The action needs to be the name of the event specified at the creation of the push.
For example, if the value of the broadcast is “CustomEvent” and considering you have
a class EventReceiver:
public class EventReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
switch (action)
{
case "CustomEvent":
//Perform the actions requested by your app
break;
}
}
}
[…]
if (localReceiver == null)
{
How to use the SDK 17
5.2.10 Broadcasts
Some specific broadcasts are sent during the management of the push notifications
(reception, display and interaction):
BROADCAST_EVENT_RECEIVED_REMOTE_NOTIFICATION : When a push is received, it contains its id and title.
This broadcast is only useful if RemoteMessageDisplayType is set to None, so you can
decide when to display the push message. In all other cases, the SDK manages
everything itself so it is not needed.
SMManager.getInstance().displayLastReceivedRemotePushNotification(activity);
This method will display the last push received (the SDK only stores the last one), using a dialog or a
dedicated Activity, depending on its type.
SMManager.getInstance().getLastRemotePushNotification();
This method will return a HashMap containing the id and title of the push (the keys are
“id” and “title”).
5.3.1 Libraries
If you plan on sending In-App messages containing “Response” type buttons, you have
to add the following third party library in your dependencies:
com.drewnoakes:metadata-extractor:2.9.1
5.3.2 Permissions
There isn’t any mandatory permission required to use the In-App messages in general. However, like for
push notifications, some In-App messages will require special permissions in order to be displayed properly.
18 How to use the SDK
If you plan on sending “Map” type messages, you might want to add one of the
following permissions in order for the user location to be displayed on the map:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
or
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Only one of the two is needed. Coarse location is less precise than fine location. Note
that if you do not add any, the map will still be displayed, just not the user location.
If you plan on sending messages that include a “Response with picture” type button,
you need to add the following permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This is needed to access the pictures on the device and call the photo app. If it is not
present in the manifest, the user will not be able do anything and a message “Not
enough permission” will appear instead.
Warning: do NOT use “READ_EXTERNAL_STORAGE” instead of
“WRITE_EXTERNAL_STORAGE”, this would result in the app crashing when the user
tries to access the camera or the gallery.
If you want to disable them at some point (or if you want to give the user the ability to do it), use the
following method:
SMManager.getInstance().disableInAppMessages();
They are enabled again by doing (this can also be used to change the refresh type):
SMManager.getInstance().enableInAppMessages(SMInAppRefreshType.Daily);
Only the title and id of each message are sent. They can be used to display some kind of inbox (a list of the
title of the messages).
The list received by this broadcast contains all the In-App messages that haven’t been read by the user
yet. Therefore, it is possible for you to receive some messages that you already got earlier.
messageId is the id of the In-App message to display (received by listening to the broadcast as discussed
in Reception of the messages) and activity the Activity that will display it.
It will be displayed the way the push notifications are.
5.3.6 Broadcasts
Some specific broadcasts are sent during the management of the In-App messages
(reception, display and interaction):
BROADCAST_EVENT_RECEIVED_IN_APP_MESSAGE : When In-App messages are received, it contains an array
of SMInAppMessages.
BROADCAST_EVENT_BUTTON_CLICKED : When a button is clicked, it contains an SMNotificationButton
object
BROADCAST_EVENT_WILL_DISPLAY_NOTIFICATION : When a message is about to be displayed
BROADCAST_EVENT_WILL_DISMISS_NOTIFICATION : When a message is about to be dismissed
5.4.1 Libraries
In order for the project to build, you must have a dependency to the following library:
• com.android.support:cardview-v7
Each one can either be displayed as a full screen dialog using the “show” method (they all extend
DialogFragment) or be used as a standard Fragment (cf. official Android documentation on Fragments).
Note that you cannot reference them directly in a layout using a “fragment” tag because they need
arguments. You have to instantiate them using the static method “newInstance” and add them
programmatically to the layout.
Once instantiated, you can call the method hasContent() to know if there is any content available for the
given category, so you can display something else instead of the fragment.
Example:
Considering the following layout:
<LinearLayout
android:layout_width="match_parent"
20 How to use the SDK
android:layout_height="wrap_content"
android:orientation="vertical">
[…]
<FrameLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:id="@+id/urlFragmentContainer"/>
</LinearLayout>
if (urlFragment.hasContent())
{
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.urlFragmentContainer, urlFragment, "URL");
fragmentTransaction.commit();
}
else
{
//do some other stuff
}
In-App contents are sorted by categories (it is one of their property at creation).
Therefore, all our Fragments require to be given that category at instantiation. Each
one will only display the In-App content corresponding to it.
SMInAppContentImageFragment and SMInAppContentUrlFragment both display only
one content at a time. It is not the case for the HTML type, so
SMInAppContentHtmlFragment needs a second argument which is the number of In-
App contents to display. Setting it to -1 means that all available contents for the given
category will be used.
5.4.3.1 Customization
The layout of the In App contents is entirely customizable. We have a default one that
is defined in the file “styles.xml”. Here is its content:
<style name="Selligent.InAppContents.Image">
<item name="android:background">#FFFFFF</item>
</style>
<style name="Selligent.InAppContents.Html.Container">
<item name="android:background">#EEEEEE</item>
<item name="android:layout_margin">0dp</item>
</style>
<style name="Selligent.InAppContents.Html.Card">
<item name="cardBackgroundColor">#FFFFFF</item>
<item name="cardCornerRadius">2dp</item>
<item name="cardElevation">2dp</item>
<item name="cardMaxElevation">2dp</item>
<item name="cardPreventCornerOverlap">true</item>
<item name="cardUseCompatPadding">true</item>
<item name="contentPadding">5dp</item>
<item name="contentPaddingBottom">5dp</item>
<item name="contentPaddingLeft">5dp</item>
<item name="contentPaddingRight">5dp</item>
<item name="contentPaddingTop">5dp</item>
</style>
<style name="Selligent.InAppContents.Html.CardContainer"/>
<style name="Selligent.InAppContents.Html.CardTitle">
<item name="android:textSize">24sp</item>
<item name="android:textColor">#000000</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:paddingRight">16dp</item>
<item name="android:paddingTop">24dp</item>
<item name="android:paddingBottom">16dp</item>
</style>
How to use the SDK 21
<style name="Selligent.InAppContents.Html.UpperDivider">
<item name="android:layout_height">0dp</item>
<item name="android:visibility">gone</item>
</style>
<style name="Selligent.InAppContents.Html.CardBody">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#555555</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:paddingRight">16dp</item>
<item name="android:paddingTop">0dp</item>
<item name="android:paddingBottom">16dp</item>
</style>
<style name="Selligent.InAppContents.Html.LowerDivider">
<item name="android:layout_height">0dp</item>
<item name="android:visibility">gone</item>
</style>
<style name="Selligent.InAppContents.Html.CardLinkContainer">
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:gravity">start</item>
</style>
<style name="Selligent.InAppContents.Html.CardLink">
<item name="android:padding">8dp</item>
<item name="android:layout_marginRight">8dp</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">#333333</item>
<item name="android:textAllCaps">true</item>
<item name="android:background">?android:attr/selectableItemBackground</item>
</style>
<style name="Selligent.InAppContents.CloseButton">
<item name="android:layout_width">30dp</item>
<item name="android:layout_height">30dp</item>
<item name="android:layout_margin">5dp</item>
<item name="android:padding">10dp</item>
<item name="android:background">@drawable/sm_ic_close_image</item>
</style>
To customize it, in your own file “styles.xml”, override the styles you want to modify.
Note that you have to copy the whole content of those styles, not only the items you
want to change, otherwise the others will be lost.
For example, if you simply want to change the background color of a Card to red, you
still have to add in your file the whole style:
<style name="Selligent.InAppContents.Html.Card">
<item name="cardBackgroundColor">#FF0000</item>
<item name="cardCornerRadius">2dp</item>
<item name="cardElevation">2dp</item>
<item name="cardMaxElevation">2dp</item>
<item name="cardPreventCornerOverlap">true</item>
<item name="cardUseCompatPadding">true</item>
<item name="contentPadding">5dp</item>
<item name="contentPaddingBottom">5dp</item>
<item name="contentPaddingLeft">5dp</item>
<item name="contentPaddingRight">5dp</item>
<item name="contentPaddingTop">5dp</item>
</style>
5.4.3.1.2 SMInAppContentImageFragment
<style name="Selligent.InAppContents.Image">
This style can be used, for example, to set a default background color when the image
does not completely fill the space reserved for the fragment.
5.4.3.1.3 SMInAppContentUrlFragment
The url is displayed using the full size of the Fragment, so there is no customization
available.
5.4.3.1.4 SMInAppContentHtmlFragment
Consider the following HTML type In App Content:
How to use the SDK 23
5.4.3.2 Refresh
If you ever want to refresh the content of one of our Fragments in case new content
is available, you can call the “refresh” method. If the fragment is not displayed, it will
just get the (possible) new content from the cache. If it is displayed, the layout will be
refreshed too.
If an Image type In-App content is marked as downloadable at creation, when the SDK retrieves
it, it will automatically start downloading the bitmap asynchronously. That bitmap can later be
obtained using the “getImage” method.
5.4.5 Broadcasts
BROADCAST_EVENT_RECEIVED_IN_APP_CONTENTS: When In-App contents are received.
BROADCAST_EVENT_BUTTON_CLICKED : When a link is clicked, it contains an SMNotificationButton object.
(cf. Local broadcasts)
5.5 Events
The following method can be used to send specific messages to the web service.
SMManager.getInstance().sendSMEvent(SMEvent event);
The kind of event message sent to the user will depend of the class of object given to
the method. All the different classes extend SMEvent. They are described in the
following points.
How to use the SDK 25
NB: Since 1.3, the data passed to the SMEvent is Hashtable<String, String> (In earlier
versions it was Hashtable<String, Object>).
5.5.1 Registration/Unregistration
5.5.1.1 SMEventUserRegister
This object is used to send a “register” event to the server with the e-mail of the user, potential data and a
callback.
Ex:
Hashtable<String, String> hash = new Hashtable<>();
hash.put("Key1", "Registration value 1");
hash.put("Key2", "Registration value 2");
hash.put("Key3", "Registration value 3");
SMEvent event = new SMEventUserRegister("[email protected]", hash,
new SMCallback()
{
@Override
public void onSuccess(String result)
{
[Do something here]
}
@Override
public void onError(int responseCode, Exception exception)
{
[Do something here]
}
});
)
SMManager.getInstance().sendSMEvent(event);
5.5.1.2 SMEventUserUnregister
This object is used to send an “unregister” event to the server with the e-mail of the user, potential data
and a callback.
Ex:
Hashtable<String, String> hash = new Hashtable<>();
hash.put("Key1", "Unregistration value 1");
hash.put("Key2", "Unregistration value 2");
hash.put("Key3", "Unregistration value 3");
SMEvent event = new SMEventUserUnregister("[email protected]", hash,
new SMCallback()
{
@Override
public void onSuccess(String result)
{
[Do something here]
}
@Override
public void onError(int responseCode, Exception exception)
{
[Do something here]
}
});
SMManager.getInstance().sendSMEvent(event);
5.5.2 Login/Logout
5.5.2.1 SMEventUserLogin
This object is used to send a “login” event to the server with the e-mail of the user, potential data and a
callback.
Ex:
Hashtable<String, String> hash = new Hashtable<>();
hash.put("Key1", "Login value 1");
26 How to use the SDK
@Override
public void onError(int responseCode, Exception exception)
{
[Do something here]
}
});
SMManager.getInstance().sendSMEvent(event);
5.5.2.2 SMEventUserLogout
This object is used to send a “logout” event to the server with the e-mail of the user, potential data and a
callback.
Ex:
Hashtable<String, String> hash = new Hashtable<>();
hash.put("Key1", "Logout value 1");
hash.put("Key2", "Logout value 2");
hash.put("Key3", "Logout value 3");
SMEvent event = new SMEventUserLogout("[email protected]", hash,
new SMCallback()
{
@Override
public void onSuccess(String result)
{
[Do something here]
}
@Override
public void onError(int responseCode, Exception exception)
{
[Do something here]
}
});
SMManager.getInstance().sendSMEvent(event);
5.5.3 Custom
5.5.3.1 SMEvent
This object is used to send a custom event to the server with some data and a callback.
Ex:
Hashtable<String, String> hash = new Hashtable<>();
hash.put("Key1", "Custom value 1");
hash.put("Key2", "Custom value 2");
hash.put("Key3", "Custom value 3");
SMEvent event = new SMEvent(hash,
new SMCallback()
{
@Override
public void onSuccess(String result)
{
[Do something here]
}
@Override
public void onError(int responseCode, Exception exception)
{
[Do something here]
}
});
SMManager.getInstance().sendSMEvent(event);
How to use the SDK 27
5.6 Geolocation
Geolocation is managed through a 3rd party library by PlotProjects, so you need to add a dependency to it
(cf. Other libraries).
To configure that library, you must add a plotconfig.json file in the asset folder of your app. There, you can
set a few properties but only one is mandatory: the Plot public token. For more information, check
PlotProjects documentation.
Example:
{
"publicToken": "YOUR_PUBLIC_TOKEN",
"debug": true
}
To tell the SDK to use the Geolocation, set the property ConfigureGeolocation to true on the SMSettings
object (cf. Optional settings).
If you set "enableOnFirstRun" to false in the plotconfig.json file, geolocation will be initialized but NOT
enabled. So the permission will not be asked to the user and you will have to enable it manually.
To do so, you can call the method SMManager.getInstance().enableGeolocation(). Note that this will
enable the geolocation but not ask the permission, you must do it yourself in that case.
This method, along with SMManager.getInstance().disableGeolocation() and
SMManager.getInstance().isGeolocationEnabled() can also be used to provide the user with an opt-in/opt-
out functionality.
NB:
• Don’t initialize or call any method of the PlotProjects API in your app, everything is managed by
our SDK.
• Our SDK sets the icon used by plot for the geolocation notifications, reusing the one that you
already gave us, so no need to specify it a second time in the config file.
• Default value for “enableOnFirstRun” is true, so if you specify only the token in the config file, you
don’t have to call any method.
5.7 Broadcasts
A certain number of broadcasts are sent from the SDK at different moments. You can listen to them to be
able to execute some code related to those events.
Refer to the template project for examples of what to do with the data sent with those broadcasts.
<category android:name="com.mycompany.myapp"/>
28 How to use the SDK
</intent-filter>
</receiver>
switch (action)
{
case SMManager.BROADCAST_EVENT_RECEIVED_REMOTE_NOTIFICATION:
String id = intent.getStringExtra("id");
String title = intent.getStringExtra("title");
break;
}
}
}
if (receiver == null)
{
receiver = new EventReceiver();
}
IntentFilter filter = new IntentFilter();
filter.addAction(SMManager.BROADCAST_EVENT_RECEIVED_REMOTE_NOTIFICATION);
registerReceiver(receiver, filter);
}
switch (action)
How to use the SDK 29
{
case SMManager.BROADCAST_EVENT_RECEIVED_IN_APP_MESSAGE:
SMInAppMessage[] messages =
(SMInAppMessage[])intent.getSerializableExtra(SMManager.BROADCAST_DATA_IN_APP_MESSAGES);
//Do some stuff
break;
case SMManager.BROADCAST_EVENT_RECEIVED_IN_APP_CONTENTS:
HashMap<String, Integer> categories = (HashMap<String, Integer>)
intent.getSerializableExtra(SMManager.BROADCAST_DATA_IN_APP_CONTENTS);
//Do some stuff
Break;
case SMManager.BROADCAST_EVENT_BUTTON_CLICKED:
SMNotificationButton button =
(SMNotificationButton)intent.getSerializableExtra(SMManager.BROADCAST_DATA_BUTTON);
//Do some stuff
break;
case SMManager.BROADCAST_EVENT_WILL_DISPLAY_NOTIFICATION:
//Do some stuff
break;
case SMManager.BROADCAST_EVENT_WILL_DISMISS_NOTIFICATION:
//Do some stuff
break;
case SMManager.BROADCAST_EVENT_RECEIVED_GCM_TOKEN:
String gcmToken = intent.getStringExtra(SMManager.BROADCAST_DATA_GCM_TOKEN);
//Do some stuff
break;
}
}
if (localReceiver == null)
{
localReceiver = new EventReceiver();
}
IntentFilter filter = new IntentFilter();
filter.addAction(SMManager.BROADCAST_EVENT_BUTTON_CLICKED);
filter.addAction(SMManager.BROADCAST_EVENT_WILL_DISMISS_NOTIFICATION);
filter.addAction(SMManager.BROADCAST_EVENT_WILL_DISPLAY_NOTIFICATION);
filter.addAction(SMManager.BROADCAST_EVENT_RECEIVED_IN_APP_MESSAGE);
LocalBroadcastManager.getInstance(this).registerReceiver(localReceiver, filter);
}
5.8 Translations
When asking for a permission, a text is displayed explaining why we need it. By default,
it is in English but a translation for few languages is provided: Dutch, Spanish, French
and German. If you want to add another language (or change the message), add under
“res” a folder named “value-[language code]” (example: to add Russian, you would
name it “value-ru”), create a “strings.xml” file and, under a <resources> tag, add:
<string name="sm_permission_explanation_location">Write here the message you want</string>
<string name="sm_permission_explanation_write_external_storage">Write here the message you
want</string>
<string name="sm_permissions_not_enough">Write here the message you want</string>
30 Proguard
6 Proguard
If you are using Proguard to minify the code of your app, add the following lines to the file proguard-
rules.pro:
-dontwarn com.selligent.sdk.**
-keep class com.selligent.sdk.* {
public private *;
}
7 Changelog
Version 2.0.0
• Added decryption of push messages
• Added Android P (API 28) support
• Added new way to retrieve FCM token (done automatically by the SDK, no extra call to our API
needed)
• Improved communication security
• Deprecated the registration to FCM through the registerDevice method. Use the JSON file instead.
Version 1.9
• Added management of buttons inside the notification.
Version 1.8
• Added management of push without In-App messages and with an action triggered when clicking
on the notification (like a deep link).
Version 1.7.2
• Corrected a bug preventing the push to be correctly handled when received while on a webview
opened by a previous notification.
Version 1.7.1
• Corrected a bug preventing the image to be correctly displayed in an InApp-Content fragment
when the image was larger than the screen.
Version 1.7.0
• Added geolocation functionality
• Android 8.1 compatible
Version 1.6.1
• Bug correction
Version 1.6.0
• Adaptations for Android O.
• Removal of the service com.selligent.sdk.GcmIntentService. If you reference it in your
AndroidManifest.xml file, remove that entry.
• The broadcast BROADCAST_EVENT_RECEIVED_REMOTE_NOTIFICATION is now deprecated due to limitations
with Android O. It is still sent but will not be received by an app targeting Android O and running
on an Android O device.
Version 1.5.0
• Image type In App contents can now be marked at creation as downloadable. In that case, after
retrieving the In App contents, the SDK will (asynchronously) download the image for each content
marked as such and store it on the device.
Troubleshooting 31
• Due to changes in the Android SDK, the inclusion of the third party library com.drewnoakes:metadata-
extractor is now required when using “Response” type buttons within a push or In-App messages.
• “Dangerous” permissions (those requiring to be explicitly granted by the user under Android 6.0
and above) are not included in the AndroidManifest.xml by the SDK anymore, it will have to be
done in the app manifest. This will allow to restrict the permissions to the functionality actually
used by the app. See each functionality to know which permission they require.
• Added support for Android SDK 24 and 25.
• Added management of “Passbook” type buttons with push, In-App message and In-App content.
Clicking on such a button will open a passbook app if the device has one or the browser instead.
Version 1.4.3
• sendSMEvent, when used with a custom event, will only send it if the data passed is new. If all
entries in the hashtable have the same values as the last time it was sent, then we won’t do
anything. If you want to log when a specific action happened and the values do not change, add a
date in the data.
Version 1.4.2
• Selligent SDK now available from JCenter
Version 1.4
• SMSettings.Theme is now deprecated. This value is not used anymore as the layout of the dialog
in now completely customizable (cf. Dialog).
• The design of a dialog does not try to adapt to the theme and the version of Android anymore,
instead there is a default material layout that is entirely customizable (cf. Dialog).
• The SetInfo event is now sent only when some of its info changed, not systematically at each start
of the SDK anymore.
• Added support for Android SDK 23 and the new way permissions are managed.
• Added In-App contents management.
8 Troubleshooting
• Q.: When I look at the devices in Campaign, why don’t they have a token?
A.: If there is no token, that means the SDK did not send it. There are a few reasons why this could
happen:
o If you don’t use the json file (cf. Creating a Google application), then you have to call the
method registerDevice(Context context) on SMManager in the onStart method of your
base Activity. Also, check if the senderId is correctly passed to the SDK
(SMSettings.GoogleApplicationId).
o If you use the json file, make sure that it is correctly placed in your app and that you
updated your build.gradle files as described on the Firebase website when adding cloud
messaging to your app.
o Mismatch sender id. This means the token used to contact the device was created with a
sender id that does not correspond to the server key stored on the Selligent platform.
Check both values on Firebase and then change the sender id given to the SDK and/or
send us the correct server key.
o Authentication failed. The server key that you gave us is not correct. Check it on Firebase
and send us the new one.
o If the push optout is 1, then the push will not be sent to the device. Maybe it was not able
to get a token or there was a call to the method disableNotifications().
If the status in Campaign is ok, then there might be something wrong in your
app.
o If you don’t use the JSON file, check that you added the correct permissions in your
manifest (cf. Permissions for Push notifications)
o Do you have another BroadcastReceiver listening to GCM/FCM push? If yes, then it might
be trying to interpret our JSON payload and crash before our receiver has time to finish
its work. You can recognize a Selligent push at its “sm” property at the root of the JSON.
o When starting the SDK, did you set the property RemoteMessageDisplayType to None?
This will prevent it from creating a notification and displaying the message when receiving
a push while the app is in foreground.
o Did you call the method disableNotifications()? This will set the push optout to 1 in
Campaign, preventing it to send push to that device.
Q.: I see “The SDK did not start correctly” in the logs, what should I do?
A: Check your code starting the SDK. Did you correctly set the 3 following values: webServiceUrl,
clientId and privateKey? If any is missing, that message will appear.
• Q.: I try to send an event but nothing happens, the callback methods are not called
A: The SDK did not start correctly (cf. previous question). You can see in the logs a message telling
you that by setting
SMManager.DEBUG = true
before calling the start method. If you did but still don’t see anything, then it means your code
starting the SDK is not called. In this case, you need to check your AndroidManifest.xml file and
make sure that your class is correctly referenced in it. If your class is called “MyCustomApplication”
and you package is “com.mycompany.myapp”, then you must have in the manifest:
<application android:name="com.mycompany.myapp.MyCustomApplication"
Note that the package name is not mandatory, you can simply specify the name of the class
preceded by a “.”.