Migration Guide
- Migration from 1.25.x to 1.26.0
- Migration from 1.24.x to 1.25.0
- Migration from 1.23.x to 1.24.0
- Migration from 1.22.x to 1.23.0
- Migration from 1.21.1 to 1.22.0
- Migration from 1.20.0 to 1.21.1
- Migration from 1.20.x to 1.21.0
- Migration from 1.19.x to 1.20.x
- Migration from 1.14.x to 1.20.x
- Migration from 1.16.x to 1.19.x
- Migration from 1.14.x to 1.16.x
- Migration from 1.13.x to 1.14.x
1.25.x to 1.26.0
Android Gradle Plugin Version Updated
The following setion only applies if you are using a version of the Android Gradle Plugin below 4.1.x
For the Android Sensibill SDK v1.26.0, we’ve upgraded our Android Gradle Plugin version to 4.1.x
and included queries
elements in our AndroidManifest.xml
files.
As a result, you may encounter compilation errors when including the SDK due to previous versions of the Android Gradle Plugin not supporting this type of element.
As a fix, Google has released new patch versions of the Android Gradle Plugin for older versions to include support for queries
elements.
Please ensure that, depending on your Android Gradle Plugin version, you upgrade to the following patch numbers or higher to successfully compile your project with the Sensibill SDK included:
- For AGP
3.5.x
-> use at least3.5.4
- For AGP
3.6.x
-> use at least3.6.4
- For AGP
4.0.x
-> use at least4.0.1
Legacy Capture Removed
As of version 1.26.0, the Sensibill Legacy Capture module has been removed from the SDK. From this point forward, the standalone-capture
module must be used instead. If you are not customizing capture at all, this change will be transparent. However, if you are launching capture via ReceiptCaptureActivityBuilder
, or applying functional capture customization through ReceiptCaptureActivityBuilder.standardBuilderCreator
, please see the Capture section of the Entry Points documentation and ensure you are still using the correct methods to achieve your desired customization.
Auth Module Refactor
A refactor has been done to some interfaces in Android Sensibill Auth modules. Specifically regarding the following interfaces: RegistrationProvider
, OAuthProvider
, SensibillAuth
.
The following section is only relevant if your current integration is using any of the above mentioned interfaces.
All methods in the above now include a new optional parameter: a CoroutineScope
with which all provided listeners will be called back upon. By default, this scope is set to a CoroutineScope
created on the Dispatchers.IO
dispatcher.
1.24.x to 1.25.0
Capture Changes
New Capture Module
A new capture module has been released with this version of the Android SDK, and by default it is set to be used instead of the (now) legacy capture module.
The legacy capture module can still be used if required when starting the capture flow from the ReceiptCaptureActivity
(via the ReceiptCaptureActivityBuilder
) by setting the following flag:
ReceiptCaptureActivityBuilder.getBuilder()
// ...
.withLegacyCaptureFlow(true)
// ...
ReceiptCaptureActivityBuilder
Configurations Updated
There have been a number of changes to the ReceiptCaptureActivityBuilder
parameters.
The most important changes are as follows:
withAdjustmentFeature
is now deprecated, to configure the availability of cropping functionality please now usewithCropEnabled
withDefaultCaptureMode
is now deprecated, to configure the initial auto-capture state please now usewithInitialAutoCaptureState
A number of new configurations have also been added. For more details of the currently available configurations, see the full documentation here
SDK-Launched Capture Customization
Also new in this version, a method has been added to customize how capture entry points from within the SDK are configured.
Updating the variable stored at ReceiptCaptureActivityBuilder.standardBuilderCreator
will cause the method provided to be used to configure the ReceiptCaptureActivityBuilder
when starting capture flows from within the SDK.
Example:
Kotlin
ReceiptCaptureActivityBuilder.standardBuilderCreator = {
val config = it ?: SBFunctionalConfiguration() // Use default config if none provided
ReceiptCaptureActivityBuilder.getBuilder()
.withShowProcessing(true)
.withSecureWindow(config.enableSecureWindow)
.withModeSummaryOnboarding(true)
}
Java
ReceiptCaptureActivityBuilder.Companion.setStandardBuilderCreator(new Function1<SBFunctionalConfiguration, ReceiptCaptureActivityBuilder>() {
@Override
public ReceiptCaptureActivityBuilder invoke(SBFunctionalConfiguration sbFunctionalConfiguration) {
SBFunctionalConfiguration config = sbFunctionalConfiguration;
// use default config if none provided
if (config == null) {
config = new SBFunctionalConfiguration();
}
return ReceiptCaptureActivityBuilder.getBuilder()
.withShowProcessing(true)
.withSecureWindow(config.getEnableSecureWindow())
.withModeSummaryOnboarding(true);
}
});
Capture Onboarding Moved
This section only is relevant to integrators who have customized the UI of the Capture Onboarding page. This change also does not apply to the old “capture tips” page, only the capture onboarding page.
The class with which the entire capture onboarding content layout can be overridden has been moved as such:
Old:
Module - sensibill-capture-camera-ui
Location - com.getsensibill.capture.controllers.CaptureTipsViewController
New:
Module - sensibill-sdk-ui
Location - com.getsensibill.ui.receipt.capture.onboarding.CaptureOnboardingActivity
The UI element styles have also changed names.
Java 8 Compatability
Starting with Version 1.25.0, the Sensibill Android SDK is built with Java 8 compatibility enabled.
In order to use the SDK, integrating projects must also build with Java 8 compatibility enabled.
In order to enable Java 8 support, add the following code snippet to your app module’s build.gradle
file
android {
// ...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
// ...
}
New Config Option - Secure Flag
A new configuration option has been added to the SBFunctionalConfiguration
class: enableSecureWindow
.
Enabling this flag will cause Sensibill Activities to set secure flags to the Activity’s window
(WindowManager.LayoutParams.FLAG_SECURE
). The effect of enabling this flag is that users will no longer be able to take screenshots, or record video from the device’s screen while a Sensibill Activity are in the foreground.
This flag defaults to false
NOTE: If a Sensibill SDK Fragment is hosted within an Activity belonging to the host app, the Activity will need to set these flags itself to enable the functionality within the given Sensibill SDK Fragment.
1.23.x to 1.24.0
Receipt Processing changes
The Receipt Processing flow (when uploading a receipt to the server) was changed on this version. It was refactored to be more consistent and reliable, and to provide the TransactionDataObserver
more meaningful status and error codes to help with troubleshooting.
The TransactionDataObserver
is an interface that is used to observe the status of a receipt being processed. It consists solely of the notify
method, which has the following signature: fun notify(transaction: Transaction)
The receipt processing changes in this version mainly affect the Transaction
object that is sent to notify
. Below is a summary of those changes.
Transaction.Status
The PENDING
status has been broken down into two new statuses: UPLOADING
and PROCESSING
.
This is in order to properly separate the image upload step from the data extraction step that happens after the image has been uploaded. Previously, PENDING
represented both the image upload and data extraction steps; therefore, it was required to check the TransactionId
field to differentiate the two states.
With this update, UPLOADING
should be interpreted as the image upload step (receipt image is being sent to the server). When the upload finishes, a new notification with the PROCESSING
status will be sent.
During the PROCESSING
state, one can now expect that the transactionId
is present in the provided Transaction
object and can be used to track the corresponding operation on the backend.
Due to the above change, PENDING
now is deprecated and will display an error when used, notifying the integrator to adopt the new UPLOADING
and PROCESSING
statuses as replacements where appropriate.
To account for these changes, if your app was previously observing Transaction.Status
your code should be updated according to the following example:
Before:
when (transaction.status) {
Transaction.Status.PENDING -> {
if (transaction.transactionId.isNullOrEmpty()) {
showMessage("Receipt Processing Started")
} else {
showMessage("Receipt Image Uploaded/Data Process Started")
}
}
Transaction.Status.COMPLETED -> showMessage("Receipt Available!")
Transaction.Status.FAILED -> showMessage("Receipt Process Failed")
}
After:
when (transaction.status) {
Transaction.Status.UPLOADING -> showMessage("Image Upload In Progress") // transactionId is NOT present here
Transaction.Status.PROCESSING -> showMessage("Receipt Image Uploaded/Data Process Started") // transactionId is present here
Transaction.Status.COMPLETED -> showMessage("Receipt Available!")
Transaction.Status.FAILED -> showMessage("Receipt Process Failed")
}
More detailed information about the different statuses can be found in the reference documentation here: Transaction.Status
Transaction.Error
Transaction
now has a new error
field.
In case of a failure in the receipt processing, the Transaction
object will contain an error explaining the reason for the failure.
Although it is not expected that errors will occur during this processing, if a transaction reaches the FAILED
state, an error will be provided to give extra information that can be shared with Sensibill for further investigation.
Possible error types:
Error | Description |
---|---|
NO_ERROR | Transaction is still in a valid state |
UNKNOWN | Error origin is not known |
UPLOAD_CANCELLED_NO_IMAGE | Transaction state is invalid for upload: image data was not found |
UPLOAD_CANCELLED_BIG_IMAGE | Transaction state is invalid for upload: image data is over the limit (2mb) |
UPLOAD_INVALID_RESPONSE | On upload request, the server returned a response that could not be interpreted and is considered invalid |
POLL_INVALID_RESPONSE | On wait request, the server returned a response that could not be interpreted and is considered invalid |
STOPPED_ON_SERVER | Server returned a stopped status for transaction |
FAILED_ON_SERVER | Server returned a failed status for transaction |
BAD_REQUEST | Server returned status code 400 (bad request) |
UNAUTHORIZED | Server returned status code 401 (unauthorized) |
FORBIDDEN | Server returned status code 403 (forbidden) |
More detailed information can be found in the reference documentation. Transaction.Error
Transaction.localId
Field localId
is now Non-Null localId: String?
-> localId: String
and you can now expect to always have a localId in the notification. If a null check was performed before on this field, that can be removed when using the newer version.
Deprecated fields in Transaction
: image
& externalTransactionId
Last call for fields image
and externalTransactionId
. These fields have not been used for some time and will be removed in a future version.
1.22.x to 1.23.0
- The Sensibill Android SDK is now compatible with the latest artifacts from Android Jetpack libraries. Jetpack comprises the androidx.* package libraries, unbundled from the platform APIs.
AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries. Reference
It is recommended to use official guides when making migrating to AndroidX. The following links are a good start:
AndroidX Overview - https://developer.android.com/jetpack/androidx
Migrating to AndroidX - https://developer.android.com/jetpack/androidx/migrate
- The
SBFunctionalConfiguration.enableFolders
front-end configuration is now deprecated and will not be handled by the SDK. To disable folders, a backend configuration must be made. -
The
SBFunctionalConfiguration.enableNotifications
front-end configuration is now deprecated and will not be handled by the SDK. To disable notifications, a backend configuration must be made. - New way to create a
TransactionDataObserver
object in Kotlin:
Before:
myTransactionDataObserver = TransactionDataObserver { transaction ->
when (transaction.status) {
// ...
}
}
After:
myTransactionDataObserver = TransactionDataObserver.fromLambda { transaction ->
when (transaction.status) {
// ...
}
}
Note: Due to our Kotlin conversion, tighter restrictions are now placed on Nullability in some interfaces. For example, the transaction parameter that comes in the
notify
method is nownon-null
.
- New way to create a
TokenProvider
object in Kotlin:
Before:
myTokenProvider = TokenProvider { oldToken, userId, listener ->
// ...
}
After:
myTokenProvider = TokenProvider.fromLambda { oldToken, userId, listener ->
// ...
}
- Certificate Pinning is now ENABLED by default. In order to disable it, add the following configuration to the
InitializationBuilder
:
val builder = InitializationBuilder(context, DefaultEnvironment.BETA_SANDBOX)
.certificatePinning(false)
.build()
SensibillSDK.initialize(builder, ...)
And for SensibillAuth as follows:
val auth = SensibillAuthBuilder(context, sensibill_env, oauthSettings)
.certificatePinning(false)
.build()
1.21.1 to 1.22.0
-
Changes have been made to
SensibillSDK.initialize()
and the old usage (just providing anInitializer
) is now deprecated. AnSDKInitializeListener
Should now be provided as well to the method andSensibillSDK.start()
should only be called after theSDKInitializeListener
calls back with a successful result. -
minSdkVersion has been changed from 18 to 21. If host application has a minSdkVersion less than 21, version must be upgraded.
-
withExternalMetadata
option in the ReceiptCaptureActivityBuilder has been deprecated. If host application is using property, it should be removed. -
Requires an upgrade of gradle build tool to at least
3.5.3
(com.android.tools.build:gradle:3.5.3)
Will run into a build time error
More than one file was found with OS independent path 'META-INF/proguard/coroutines.pro
if using a build tool less than3.5.3
.
Note: If updating the gradle version is not possible, adding the following rule to your build.gradle can potentially mitigate the issue:
android { ... packagingOptions { pickFirst('META-INF/proguard/coroutines.pro') } ... }
1.21.0 to 1.21.1
- All necessary Sensibill dependencies are now included in
sensibill-sdk-all
. You may need to remove other Sensibill dependencies from yourbuild.gradle
file when migrating to this and future versions.
1.20.x to 1.21.0
- No interface changes between 1.20.x to 1.21.x
1.19.x to 1.20.x
- No interface changes between 1.19.x to 1.20.x
1.14.x to 1.20.x
Build Dependency Changes
Package / Class Name Change
Deprecated Function
1.16.x to 1.19.x
- No interface changes between 1.16.x to 1.19.x
1.14.x to 1.16.x
Build Dependency Changes
- Compile SDK version: 28
- Target SDK version: 28
- Build Tools version: 28.0.3
- Android Support Library version: 28.0.0
- Android Gradle Tool version: 3.2.0
Package / Class Name Change
1.14.x | 1.16.x |
---|---|
com.getsensibill.oauthclient.OauthUser | com.getsensibill.oauthclient.OauthSession |
Deprecated Function
Deprecated function | Reason |
---|---|
InitializationBuilder.transactionDataObserver | Transaction Data Observer is no longer added to the InitializationBuilder. Added to SensibillSDK directly (SensibillSDK.addTransactionDataObserver()) |
InitializationBuilder.receiptDataObserver | Receipt Data Observer is no longer added to the InitializationBuilder. Added to SensibillSDK directly (SensibillSDK.addReceiptDataObserver()) |
Notes for Migration
- Function to add TransactionObserver and ReceiptDataObserver moved to SensibillSDK object from InitializationBuilder
- The above must be done after initialization
- Example:
before:
// Create Observers
myTransactionDataObserver = MyTransactionDataObserver()
myReceiptDataObserver = MyReceiptDataObserver()
// Add to initializer
initializationBuilder.transactionDataObserver(myTransactionDataObserver)
initializationBuilder.receiptDataObserver(myReceiptDataObserver)
// Initialize
mInitializer = initializationBuilder.build()
SensibillSDK.getInstance().initialize(mInitializer)
after:
// Create Observers
myTransactionDataObserver = MyTransactionDataObserver()
myReceiptDataObserver = MyReceiptDataObserver()
// Initialize
SensibillSDK.getInstance().initialize(mInitializer)
// Add to SDK
SensibillSDK.addTransactionDataObserver(myTransactionDataObserver)
SensibillSDK.addReceiptDataObserver(myReceiptDataObserver)
- It is also possible now to remove the observers by calling:
SensibillSDK.removeTransactionDataObserver(myTransactionDataObserver)
SensibillSDK.removeReceiptDataObserver(myReceiptDataObserver)
1.13.x to 1.14.x
Feature Added
ReceiptCaptureActivityBuilder used to create intent for ReceiptCapture
Function Name Change
Old Function Name | New Function Name |
---|---|
OAuthSettings.getApikey() | OAuthSettings.getApiKey() |
SensibillSDK.getInstance() | SensibillSDK.INSTANCE (in Java) |
Package / Class Name Change
Migration to core module
1.13.x | 1.14.x |
---|---|
com.getsensibill.sensibillsdk.interfaces.OnTrackEventListener | com.getsensibill.core.analytic.OnTrackEventListener |
com.getsensibill.sensibillsdk.tracker.events.AnalyticsEvent | com.getsensibill.core.analytic.OnTrackEventListener |
com.getsensibill.sensibillsdk.utilities.base.ActivityLifecycleListener | com.getsensibill.core.ActivityLifecycleListener |
com.getsensibill.sensibillsdk.interfaces.TokenProvider | com.getsensibill.tokenprovider.TokenProvider |
com.getsensibill.sensibillsdk.utilities.Transaction | com.getsensibill.core.analytic.Transaction |
com.getsensibill.sensibillsdk.utilities.TransactionDataObserver | com.getsensibill.core.TransactionDataObserver |
com.getsensibill.sensibillsdk.InitializationBuilder | com.getsensibill.core.InitializationBuilder |
com.getsensibill.sensibillsdk.Initializer | com.getsensibill.core.Initializer |
com.getsensibill.sensibillsdk.SensibillSDK | com.getsensibill.core.SensibillSDK |
com.getsensibill.sensibillsdk.interfaces.LoginError | com.getsensibill.core.LoginError |
com.getsensibill.sensibillsdk.interfaces.SDKStartup | com.getsensibill.core.SDKStartup |
Migration to UI module
1.13.x | 1.14.x |
---|---|
com.getsensibill.sensibillsdk.SBMainTabsFragment | com.getsensibill.ui.SBMainTabsFragment |
com.getsensibill.sensibillsdk.receipt.capture.ReceiptCaptureActivity | com.getsensibill.ui.receipt.capture.ReceiptCaptureActivity |
com.getsensibill.sensibillsdk.receipt.controllers.detail.ReceiptDetailActivity | com.getsensibill.ui.receipt.controllers.detail.ReceiptDetailActivity |
com.getsensibill.sensibillsdk.receipt.controllers.detail.ReceiptDetailActivity | com.getsensibill.ui.receipt.controllers.detail.ReceiptDetailActivity |
Deprecated Function
SensibillSDK.isInitialized() - removed, now use SensibillSDK.state() to check state of SDK. Check migration notes for details
SensibillSDK.login() - removed, replaced to use SensibillSDK.start(). Check migration notes for details
Notes for migration
Update Package Names
-
many of the non-ui classes under com.getsensibill.sensibillsdk are now under com.getsensibill.core
-
token provider is now separate module: com.getsensibill.tokenprovider
-
getNewAuthToken() has new implementation. From synchronous to async
-
SessionListener under sensibillAuth module
-
UI elements now under getsensibill.ui
SensibillSDK object
- SensibillSDK functions can be called directly. No more .getInstance()
- in Java, still call .INSTANCE
SensibillSDK.verifyToken removed
- In sensibill-client to be released in -> “com.getsensibill:sensibill-client:1.14.8”
SensibillSDK.login(accessToken, username, cb) -> SensibillSDK.start(username, cb)
- No access token passed on start, uses provided token provider to get access token on start.
SensibillAuth.startLibrary()
-
Not available anymore
-
Authentication is not a wrapper of SDK
-
Must check if SensibillSDK is initialized
Authentication
-
Was renamed to SensibillAuth
-
SensibillAuthBuilder was renamed to AuthenticationBuilder
TokenProvider is the only way to Initialization
-
Must use Authentication object if no custom TokenProvider.
-
For the SensibillSDK interface, one can call functions directly. No more .getInstance() (in Java, still call .INSTANCE)
-
SensibillAuth.startLibrary() is not available anymore. SensibillSDK.start() is used instead. But before, check if SensibillSDK is already initialized.
before:
mSensibillAuth.startLibrary(mInitializer, username, listener)
after:
if (SensibillSDK.getState() == CoreState.INITIALIZED) {
SensibillSDK.start(username, listener)
}
- SensibillSDK.login(accessToken, username, cb) is also not needed anymore, SensibillSDK.start(username, cb) will be enough. Since now token provider is added on the initialization, there is no need for a separate method to start with token. And token provider will give access token during on start process.