Use customer-facing platform
Prerequisite
This tutorial assumes you're using clover-cfp-sdk
version 4.1.0 or higher.
Customer Facing Platform (CFP)
The Customer Facing Platform (CFP) provides the capability for custom activities to be launched and controlled on the customer facing device in a tethered configuration, including Clover Station Pro or a Clover Station tethered to a Clover Mini. The clover-cfp-sdk
provides support for custom activities, as well as launching and communicating with custom activities.
Clover CFP SDK
The clover-cfp-sdk
library contains classes that support building a custom activity and controlling a custom activity remotely. For custom activities, clover-cfp-sdk
provides a base implementation of an activity to simplify custom activity development. You can extend it to facilitate setting result values, as well as sending and receiving string messages between the POS and Custom Activity. For controlling the custom activity, clover-cfp-sdk
provides the RemoteDeviceConnector
class.
The SDK is divided into two packages for handling separate responsibilities:
com.clover.cfp.activity
- Customer-facing device classescom.clover.cfp.connector
- Merchant-facing device classes
The SDK is available from MVN Repository or The Central Repository.
Custom activities (customer-facing device) classes
The com.clover.cfp.activity.helper
- CloverCFPActivityHelper
, as well as CloverCFPCommsHelper
provide utilities for customer-facing activities. They provide methods for handling messages sent from the POS, as well as some convenience behavior like setting the result and finishing and standard 4-finger exit behavior. The deprecated class of com.clover.cfp.activity
CloverCFPActivity
is a convenience base class leveraging the helper classes, but requires extending it so is no longer the preferred option.
public class CloverCFPActivityHelper {
public String getInitialPayload() // payload used to start custom activity
public void setResultAndFinish(int result, String data); // used to set the result code and payload returned to the RemoteDeviceConnector
}
public class CloverCFPCommsHelper {
public void sendMessage(String payload) throws Exception; // used to send a payload back to the RemoteDeviceConnector
public void onMessage(String payload); // override to receive payload messages from the RemoteDeviceConnector
}
Example Activity using CloverCFPActivityHelper
public class CustomerActivity extends Activity {
private CloverCFPActivityHelper activityHelper;
private CloverCFPCommsHelper commsHelper;
@Override protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_customer);
activityHelper = new CloverCFPActivityHelper(this);
commsHelper = new CloverCFPCommsHelper(this, getIntent(), new MessageListener(){
public void onMessage(String payload) {
// do something with a message from the RemoteDeviceConnector
// RemoteDeviceConnector is requesting the
// CustomActivity finishes itself
if ("FINISH".equals(message)) {
setResultAndFinish(RESULT_OK, "{\"action\":\"FINISHING\"}");
}
}
});
String initialPayload = activityHelper.getInitialPayload();
// do something with the payload
}
public void clickYes(View view) {
try {
sendMessage("{\"action\":\"YES\"}");
} catch(Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
}
}
public void clickNo(View view) {
try {
sendMessage("{\"action\":\"NO\"}");
} catch(Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
}
}
public void clickDone(View view) {
activityHelper.setResultAndFinish(RESULT_OK, "{\"action\":\"DONE\"}");
}
}
AndroidManifest.xml
definition for a custom activity
<activity android:name=".CustomerActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="com.yourdomain.ACTIVITY_NAME"/>
<category android:name="com.clover.cfp.ACTIVITY"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Remote Device Connector (merchant-facing device) classes - com.clover.cfp.connector
RemoteDeviceConnector
is the main class used to interact with the customer-facing device, including starting and communicating with a custom activity. In addition to starting a custom activity and sending a message to the activity, the connector also provides the ability to query the status of the device and reset the state of the device if needed.
NOTES
- The Remote Device Connector (merchant-facing device) classes - com.clover.cfp.connector is not applicable to REST Pay Display integrations.
- Applications can only start custom activities when the device is in an idle state (for example, at the Welcome, Display Order, or Thank You screen).
Starting custom activities and getting activity results
An initial string payload can be passed in during construction or returned through an activity result. The initial payload can be passed in through the CustomActivityRequest
and retrieved in the custom activity using the SDK's CFPConstants.EXTRA_PAYLOAD
extra. The same key can be used to return a value in the result, or use the CloverCFPActivity.setResultAndFinish
(int result, string payload) call to finish the CustomActivity
.
NOTE
All methods except
disconnect()
must be called off the main/UI thread.
Simple POS activity starting a custom activity on the customer-facing device
public class POSActivity extends Activity {
private static final String CUSTOM_ACTIVITY_NAME = "com.yourdomain.ACTIVITY_NAME";
private Executor executor = Executors.newFixedThreadPool(3);
private RemoteDeviceConnector remoteDeviceConnector;
@Override protected void onCreate(Bundle savedInstance) {
remoteDeviceConnector = new RemoteDeviceConnector(this, CloverAccount.getAccount(this));
}
@Override protected void onResume() {
super.onResume();
final String payload = "{\"msg\"=\"Initial...\"}"; // if you need an inital payload
final CustomActivityRequest car = new CustomActivityRequest(CUSTOM_ACTIVITY_NAME, payload);
executor.execute(()->{
remoteDeviceConnector.resetDevice(new ResetDeviceRequest());
remoteDeviceConnector.startCustomActivity(car, new CustomActivityListener(){
@Override public void onMessageFromActivity(MessageFromActivity message) {
// handle message from the CustomActivity
}
@Override public void onCustomActivityResult(CustomActivityResponse response) {
// handle the result of the CustomActivity
}
});
});
}
@Override protected void onPause() {
super.onPause();
executor.execute(()->{
remoteDeviceConnector.sendMessageToActivity(new MessageToActivity(CUSTOM_ACTIVITY_NAME, "FINISH");
remoteDeviceConnector.disconnect();
});
}
}
Helper classes
Starting with version 4.1, helper classes were added to the sdk to remove the need to subclass CloverCFPActivity. There are 2 helper classes:
CloverCFPActivityHelper—Provides 4-finger exit support, simplifies getting the initial payload, and simplifies setting the result in the proper format and finishing the activity.
CloverCFPCommsHelper—Provides methods to enable communicating between the point of sale (POS) and Custom Activity
Note: Use of helper classes is not required to start a custom activity.
public class MyCFPActivity extends Activity implements CloverCFPCommsHelper.MessageListener {
CloverCFPActivityHelper activityHelper;
CloverCFPCommsHelper commsHelper;
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_mycfp);
activityHelper = new CloverCFPActivityHelper(this);
commsHelper = new CloverCFPCommsHelper(this, getIntent(), this);
}
public void onDestroy() {
activityHelper.dispose();
commsHelper.dispose();
super.onDestroy();
}
public void onMessage(String payload) {
// called when remoteDeviceConnector.sendMessageToActivity(...)
// is invoked from POS
if("FINISH".equals(payload)) {
finishWithPayloadToPOS("");
}
}
public void doSendMessageToPOS() {
try {
String payload = "some message";
commsHelper.sendMessage(payload); // send a message to the RemoteDeviceConnector instance
} catch(Exception e) {
// log the excption, update ui, etc.
}
}
public void finishWithPayloadToPOS(String resultPayload) {
activityHelper.setResultAndFinish(RESULT_OK, resultPayload);
}
}
Updated 10 months ago