Launching on Android
Overview
The Capture Flow includes capturing receipt images, uploading the resulting images, and notifying a provided listener of flow progress.
To launch the capture flow, use the CaptureFlowCoordinator
class. The CaptureFlowCoordinator
can be used from any AppCompatActivity
.
Info
Before launching the Capture Flow, please follow the Installation and Authentication steps, as well as Initialize and Start SDK.
Basic Steps
Create a CaptureFlowListener (or, alternatively you can have your host
Activity
implementCaptureFlowCoordinator.CaptureFlowListener
). Please note: theTransacting
state only applies if you are configured to use the v1 (receipts) endpoints, andDocumentUploading
only applies if you are configured to use the v2 (documents) endpoints. Please only include one of these options.Create a CaptureFlowCoordinator in the
Activity
from which you wish to launch the Capture Flow.Launch the Capture Flow when desired by calling CaptureFlowCoordinator.launchCaptureFlow . Please note: that the
DocumentType
configuration is only valid if configured to use the v2 (documents) endpoints. If this configuration is provided when NOT configured to use v2 endpoints, an exception will be thrown.This operation will launch the capture UI, as well as trigger the upload any resulting images.
CaptureFlowListener
will continue receiving progress updates. You can handle the updates according to the needs of your app.
Additional References:
Example
// Step 1
private val captureFlowListener: CaptureFlowCoordinator.CaptureFlowListener = object : CaptureFlowCoordinator.CaptureFlowListener {
override fun onCaptureFlowUpdate(newState: CaptureFlowState, externalAccountTransactionId: String?) {
when (newState) {
is CaptureFlowState.ImagesCaptured -> {
// Handle the state that images have just been captured
val imagesPendingUpload: List<PendingUploadItemData> = newState.imagesPendingUpload
}
is CaptureFlowState.FLOW_CANCELLED -> { /* Handle the user cancelling the flow */ }
is CaptureFlowState.Error -> {
// Handle an error occurring during the flow
val error = newState.exception
}
// **ONLY APPLICABLE IF CONFIGURED USING API V1 (RECEIPTS) ENDPOINTS**
is CaptureFlowState.Transacting -> {
// Handle receipt upload transaction updates that will occur after the image has been captured
// and the receipt is uploading
val transaction = newState.transaction
val currentTransactionStatus = transaction.status
}
// **ONLY APPLICABLE IF CONFIGURED USING API V2 (DOCUMENTS) ENDPOINTS**
is CaptureFlowState.DocumentUploading -> {
// Handle document upload progress updates that will occur after the image has been captured and the
// Document is uploading
val update = newState.update
val status = update.status
}
}
}
}
// ...
// Step 2
private val captureFlow = CaptureFlowCoordinator(this)
// Step 3
captureFlow.launchCaptureFlow(
// (Required) Your capture flow listener
listener = captureFlowListener,
// (Optional, default null) captureConfig. If none provided, will default to the default config for the
// provided document type
config = null,
// (Optional, default null) external account transaction id to add an external account
// transaction id to a captured document
externalAccountTransactionId = "myExtTxnId",
// (Optional, default RECEIPT) ONLY APPLICABLE IF USING V2 (DOCUMENTS) API ENDPOINTS
// The type of document to capture, receipt or invoice
documentType = DocumentType.RECEIPT
)
// Step 1
private CaptureFlowCoordinator.CaptureFlowListener captureFlowListener = new CaptureFlowCoordinator.CaptureFlowListener() {
@Override
public void onCaptureFlowUpdate(@NotNull CaptureFlowState newState, @Nullable String externalAccountTransactionId) {
if (newState instanceof CaptureFlowState.ImagesCaptured) {
// Handle the state that images have just been captured
final CaptureFlowState.ImagesCaptured imagesCapturedState = (CaptureFlowState.ImagesCaptured) newState;
final List<PendingUploadItemData> imagesPendingUpload = imagesCapturedState.imagesPendingUpload;
} else if (newState instanceof CaptureFlowState.FLOW_CANCELLED) {
// Handle the user cancelling the flow
} else if (newState instanceof CaptureFlowState.Error) {
// Handle an error occurring during the flow
final CaptureFlowState.Error errorState = (CaptureFlowState.Error) newState;
final Exception error = errorState.getException();
// **ONLY APPLICABLE IF CONFIGURED USING API V1 (RECEIPTS) ENDPOINTS**
} else if (newState instanceof CaptureFlowState.Transacting) {
// Handle receipt upload transaction updates that will occur after the image has been captured
// and the receipt is uploading
final CaptureFlowState.Transacting transactingState = ((CaptureFlowState.Transacting) newState);
final Transaction transaction = transactingState.getTransaction();
final Transaction.Status currentTransactionStatus = transaction.getStatus();
// **ONLY APPLICABLE IF CONFIGURED USING API V2 (DOCUMENTS) ENDPOINTS**
} else if (newState instanceof CaptureFlowState.DocumentUploading) {
// Handle document upload progress updates that will occur after the image has been captured and the
// Document is uploading
final DocumentUploadUpdateData update = ((CaptureFlowState.DocumentUploading) newState).getUpdate();
final DocumentStatus status = update.getStatus();
}
}
};
// ...
// Step 2
private CaptureFlowCoordinator captureFlow = new CaptureFlowCoordinator(this);
// Step 3
captureFlow.launchCaptureFlow(
// (Required) Your capture flow listener
captureFlowListener,
// (Optional, default null) captureConfig. If none provided, will default to the default config for the
// provided document type
null,
// (Optional, default null) external account transaction id to add an external account
// transaction id to a captured document
"myExtTxnId",
// (Optional, default RECEIPT) ONLY APPLICABLE IF USING V2 (DOCUMENTS) API ENDPOINTS
// The type of document to capture, receipt or invoice
DocumentType.RECEIPT
);
Capture Flow Customization
Additional Arguments
Additional arguments can be provided to the CaptureFlowCoordinator.launchCaptureFlow()
call to customize the behaviour of the Capture Flow.
config: CaptureConfig
: ACaptureConfig
object can be provided to customize the behaviour of capture itself. Please see the Reference Documentation for details on the configurable properties ofCaptureConfig
.If your project is in Kotlin it is recommended to create a custom
CaptureConfig
usingCaptureConfig.defaultConfig.copy()
and providing the customizations required to thecopy
method.externalAccountTransactionId: String?
: If the receipt that is about to be captured should be linked with an external transaction (eg. banking transaction), that transaction’s ID can be provided here. When providing anexternalAccountTransactionId
,CaptureConfig.maxImages
must be set to1
. If this rule is ignored, the capture flow will throw an exception. See Bank Transaction Linking page for more details.
Customizing the Default CaptureConfig
By default, every created instance of the capture flow will use the default CaptureConfig
object: CaptureConfig.defaultConfig
.
This default CaptureConfig
can be modified to globally change the default capture configuration. Once a new default config has been set, every subsequent instance of any capture use case will use that default, unless otherwise directly overridden.
This property lives in a Kotlin object
(singleton), so it should be customized either in your Application.onCreate
, or when you set up the SensibillSDK
. The customized values will then be used from that point onward.
// Use default settings, overriding the maximum captured image limit to be 5
CaptureConfig.defaultConfig = CaptureConfig.defaultConfig.copy(
maxImages = 5
)
// Use default settings, overriding the maximum captured image limit to be 5
final CaptureConfig intendedDefaultConfig = new CaptureConfig(
true,
true,
FlashMode.FLASH_MODE_AUTO,
true,
true,
true,
true,
5,
true,
true,
false,
false,
true,
true
);
CaptureConfig.Companion.setDefaultConfig(intendedDefaultConfig);
Branding
You can also customize Capture appearance (colors, fonts), and Tips. See Branding for more information.
Tips Customization
To override any string
resources mentioned below, add the exact string key to your own strings.xml
file.
For example, for the string key sb__tips_description_flattenreceipt
, add the following to override it:
<string name="sb__tips_description_flattenreceipt">My tip description</string>
To override and drawable
resources mentioned below, create a new drawable with the exact name as the one that you wish to override.
The list of overridable keys is listed on Customizing Tips page.