Android SDK
The Rover SDK is an Android framework for connecting your app to the Rover Platform. The SDK is 100% open-source and available on GitHub.
Install the SDK
Before continuing with the installation of the Rover SDK, please make sure you have setup you project and Android app in the Firebase Console.
Requirements
- Android Studio 2.1.2 or higher
- Min Android SDK 18
- GooglePlayServices 9.0.2 on device
- Firebase account
JCenter
The easiest way to get Rover into your Android project is to use the JCenter Maven repository. Just add the following line to the dependencies
section of your module’s build.gradle
file:
compile 'io.rover.library:rover:1.16.0'
Initialization
The Rover SDK MUST be initialized inside the Application base class onCreate
method. If your Android application doesn’t already have an Application base class, follow these instructions to create one.
Add the following snippet to your Application’s onCreate
method:
RoverConfig config = new RoverConfig.Builder()
.setApplicationToken("YOUR APPLICATION TOKEN HERE")
.build();
Rover.setup(this, config);
Beacons and Geofences
Call the startMonitoring()
method to begin monitoring for beacons and geofences. You may choose to do this step in any Activity of your choice.
IMPORTANT As of the Marshmallow release, the Android OS requries this to be wrapped in a permission check block. An example of a backwards compatible way to do this is shown below:
public class MainActivity extends AppCompatActivity {
public void startRoverMonitoring() {
if (Build.VERSION.SDK_INT >= 23) {
// Marshmallow+
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
} else {
Rover.startMonitoring();
}
} else {
// Pre-Marshmallow
Rover.startMonitoring();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Rover.startMonitoring();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
Proximity Events
Rover uses the observer pattern to notify the developer of proximity events. The Rover.addObserver();
method accepts any object implementing one or more of the RoverObservers.
Here’s an example of an Activity
that adds itself as an observer and implements the MessageDeliveryObserver
interface.
public class MyActivity extends AppCompatActivity implements RoverObserver.MessageDeliveryObserver {
@Override
protected void onCreate(bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Rover.addObserver(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
Rover.removeObserver(this);
}
@Override
public void onMessageReceived(Message message) {
Log.i("RoverMessage", "Received message: " + message.getText());
}
}
IMPORTANT Notice that the example removes itself as an observer in the onDestory
method. This is required in order for the class to properly deallocate itself. Any call to Rover.addObserver();
must be balanced with a corresponding call to Rover.removeObserver();
.
Messages
Using the Rover Messages App you can create messages that are delivered to your users when a proximity event is triggered or on a specific date and time. You can attach push notifications to your messages that will be delivered along with your messages. Additionally you can attach content to your messages. The content can be a landing page authored in the Rover Messages App or it can simply link to a website. A message can also trigger functionality within your app through a deep link and can have custom data attached.
Notifications
IMPORTANT Rover reserves the key _rover
in the notification’s data payload. Please ensure all notifications not originating from the Rover Platform do not specifiy this key.
In order to have notification and messages working, Rover needs your FCM server key. Use this guide to upload your configure Rover with your FCM setup.
If you like fine-grained control over notifications, you must register a NotificationProvider during initialization.
RoverConfig config = new RoverConfig.Builder()
.setApplicationToken("YOUR APPLICATION TOKEN HERE")
.setNotificationProvider(new NotificationProvider() {
...
})
.build();
Rover.setup(this, config);
Check the Notification Provider file for more documentation on methods to customize behavior.
Custom FirebaseMessagingService
If your app is already currently using FCM and implements the FirebaseMessagingService
, helper methods have been provided to handle Rover notifications. The following example demonstrates these methods
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import io.rover.Rover;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (Rover.isRoverMessage(remoteMessage)) {
Rover.handleRemoteMessage(remoteMessage);
return;
}
// ...
// Parse the message as your own
}
}
Default Back Button Behaviour
If you do not provide a Notification Provider to Rover the default back behaviour is to use the parent activity provided in your AndroidManifest file. This is only the case when a message will launch a LandingPage or an Experience. The following example demonstrates that when the back button is pressed after launching an Experience from a notification the MainActivity will run.
...
<activity android:name="io.rover.ExperienceActivity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
...
Inbox
Most applications provide means for users to recall messages. You can use the onMessageReceived(Message message)
callback on a MessageDeliveryObserver
to map and add Rover messages to your application’s inbox as they are delivered. You may also rely solely on Rover for a simple implementation of such inbox if your application doesn’t already have one:
Rover.reloadInbox(new Rover.OnInboxReloadListener() {
public void onSuccess(List<Message> messages) {
// Add to your adapter
}
public void onFailure() {}
});
Note that the reloadInbox
method will only return messages that have been marked to be saved in the Rover Messages app.
See the MessageFragment in the example app for a quick implementation.
Deleting messages from the Rover inbox
Rover provides a simple method for deleting messages from the inbox, this can be accomplished with just the message id or the message object itself. Refer to the following snippet on how deletion works
// message -> io.rover.model.Message
Rover.deleteMessage(message, new Rover.OnDeleteMessageListener() {
@Override
public void onSuccess() {
// update your adapter here if presenting messages in a listview
Log.i("MyApp", "Message has been deleted");
}
@Override
public void onFailure() {
Log.e("MyApp", "Failed to delete message");
}
});
Updating read status of a message
Every Rover message has a flag indicating if the message has been read or not. This can be useful in your application if you wish to display an indicator if the user has interacted with the message before. To accomplish this behaviour Rover provides a patchMessage
method to update the flag. The following demonstrates how to set a message read status to true
if (!message.isRead()) {
message.setRead(true);
Rover.patchMessage(message, new Rover.OnPatchMessageListener() {
@Override
public void onSuccess() {
Log.i("MyApp", "Message has now been read");
}
@Override
public void onFailure() {
Log.e("MyApp", "Something failed while trying to update the status");
}
});
}
Screen Activity
If the message contains a landing page you probably want to present an activity for it. The getLandingPage()
method of a Message
object is of type Screen
. You can launch the ScreenActivity
using an Intent which has the Screen
object in its extras under the key ScreenActivity.INTENT_EXTRA_SCREEN
.
Intent intent = new Intent(this, ScreenActivity.class);
intent.putExtra(ScreenActivity.INTENT_EXTRA_SCREEN, message.getLandingPage());
startActivity(intent);
Customer Identity
By default the Rover platform will assign a unique identifier to each customer who installs your application. However you may choose to assign your own identifiers. This is particularly useful for mapping data from the Rover Analytics app or if a customer is using your application on multiple platforms. To accomodate this Rover saves customer info to device storage so that it persists across sessions. The following snippet demonstrates assigning your own customer identifier:
Rover.identify(new Traits().putIdentifier("hello123"));
In addition to identifiers, you may provide other user attributes for more personlized and segmented messaging via the Rover Messages app.
Rover.identify(new Traits()
.putAge(44)
.putEmail("hello@example.com")
.addTags("a", "b", "c")
.putPhoneNumber("555-555-5555"));
Traits are persisted to and restored from disk. This insures once traits have been set they stay set until changed. However if your app has a login logout feature you will want to make sure to clear all the previous traits that have been stored. To do this simply call
Rover.clearCustomer()