-
Notifications
You must be signed in to change notification settings - Fork 5
Upgrade Guide
As of 7.2.0, in the IProov.Options, ui.promptTextColor
replaces ui.footerTextColor
, which is now deprecated.
Requires your module compileSdkVersion
to be Android API 31+.
If you require your compileSdkVersion
to be 29+ you can add the following to your module's gradle.build
file in the defaultConfig
section:
configurations.all { resolutionStrategy { force 'androidx.appcompat:appcompat:1.3.1' } }
options.network.certificates
has changed type from Array<String>
to Array<Object>
. It is now possible to pass a mixed array containing elements of either:
-
String
values (existing behaviour) - these will be treated as paths to the certificate (included in the raw folder). -
byte[]
values (new behaviour) - these will be treated as the certificates themselves.
Minimum SDK version has been increased to Android API 21 (Lollipop), this removes use of insecure TLS Versions
The paths of various UI customization options has been updated to separate the Genuine Presence and Liveness Assurance UI options:
Old name | New name |
---|---|
Options.ui.autoStartDisabled |
Options.ui.genuinePresenceAssurance.autoStartDisabled |
Options.ui.notReadyTintColor |
Options.ui.genuinePresenceAssurance.notReadyTintColor |
Options.ui.readyTintColor |
Options.ui.genuinePresenceAssurance.readyTintColor |
Options.ui.progressBarColor |
Options.ui.genuinePresenceAssurance.progressBarColor |
Options.ui.livenessTintColor |
Options.ui.livenessAssurance.primaryTintColor |
Options.ui.livenessScanningTintColor |
Options.ui.livenessAssurance.secondaryTintColor |
The following options have been removed:
Removed options |
---|
Options.network.disableCertificatePinning * |
Options.ui.useLegacyConnectingUI |
Options.ui.loadingTintColor |
Options.ui.scanLineDisabled |
* Pinning can be disabled by passing an empty array into Options.network.certificates
-
IProov.keyPair.sign
method now throws anIProovException
instead ofKeyStoreManagerException
-
KeyStoreManagerException
,LightingModelException
andEncoderException
have been removed and are represented byUnexpectedErrorException
The following keys have been added, renamed or removed:
Old key | New key |
---|---|
New value | iproov__error_unexpected_error |
iproov__error_no_listener_exception |
iproov__error_listener_not_registered |
iproov__error_invalid_options_error |
iproov__error_invalid_options |
iproov__error_encoder |
Removed |
iproov__error_lighting_model |
Removed |
iproov__error_keystore_manager_exception |
Removed |
The IProov.launch()
methods have been improved in three important ways.
- Old deprecated
launch()
methods from v5.0 have been removed. These ones took alistener: Listener
parameter. You can no longer use them. If you hadn't already updated please look below in Upgrading to v5.1.0 and to Upgrading to v6.0 Multiple Listener callbacks - Of the remaining three
launch()
methods from v5.1 onwards, these have been reduced to two since thestreamingUrl: String
parameter is now mandatory. -
launch()
methods can now throw a subset ofIProovException
(namelyListenerNotRegisteredException
,MultiWindowUnsupportedException
,CaptureAlreadyActiveException
), under conditions known to prevent an IProov capture from starting at all. Therefore these methods now require exception handling (perhaps atry {} catch {}
).
The use of launch()
calls might look like this:
Kotlin
try {
IProov.launch(context, streamingUrl, token)
} catch (ex: IProovException) {
// Handle failure because of ListenerNotRegisteredException, MultiWindowUnsupportedException or CaptureAlreadyActiveException
}
try {
IProov.launch(context, streamingUrl, token, options)
} catch (ex: IProovException) {
// Handle failure because of ListenerNotRegisteredException, MultiWindowUnsupportedException or CaptureAlreadyActiveException
}
The IProov Android Biometric SDK has had some significant improvements made to it. Listed here are the breaking changes you need to know about.
The onSuccess()
and onFailure()
callbacks methods in IProov.Listener
have changed signature from multiple values to a single class.
In version 5.2.2, the signatures looked like this:
Kotlin
override fun onSuccess(token: String) {
// The user was successfully verified/enrolled and the token has been validated.
// The token passed back will be the same as the one passed in to the original call.
}
override fun onFailure(reason: String?, feedback: String?) {
// The user was not successfully verified/enrolled, as their identity could not be verified,
// or there was another issue with their verification/enrollment. A reason (as a string)
// is provided as to why the claim failed, along with a feedback code from the back-end.
}
In version 6.0+, the success and failure methods allow for further information to be passed, and to allow future extensibility, but aggregating values into a class. Also the token is now also passed in onFailure
.
You should be able to move from v5.2.2 to v 6.0.0 simply as follows:
Kotlin
override fun onSuccess(result: IProov.SuccessResult) {
// The user was successfully verified/enrolled and the token has been validated.
Log.i("Success", "Token: ${result.token}")
}
override fun onFailure(result: IProov.FailureResult) {
// The user was not successfully verified/enrolled, as their identity could not be verified,
// or there was another issue with their verification/enrollment.
Log.i("Failure", "Token: ${result.token}, reason: ${result.reason} feedbackCode: ${resule.feedbackCode}")
}
The previous IProov.unregisterListener();
was error prone and so it now expects to be passed a listener thus: IProov.unregisterListener(listener);
. This allows for multiple listeners to be registered and unregistered within their own scope without having any adverse effects of other code's listener(s).
Also IProov.registerListener(listener);
will no longer immediately replay the last event unless you use IProov.registerListener(listener, true);
v6.0 introduces connection callbacks, which means that the iProov UI is not displayed until the connection to iProov's servers has been established. This means that you can keep the user in your app and provide the appropriate UI until the connection has been established.
You must now implement new the onConnecting()
and onConnected()
statuses in the iProov listener.
If you do not wish to implement your own custom UI for connecting and revert to the legacy behavior from v5.2 and earlier, you can opt-out of this new feature by setting options.ui.useLegacyConnectingUI = true;
which will continue to show the connecting indication within the iProov SDK itself.
Please note that the useLegacyConnectingUI
option is deprecated, and will be removed in a future version of the SDK. All customers are advised to adopt the new connection callbacks as soon as possible.
Also be advised that options.ui.loadingTintColor
has also been deprecated, as this only takes effect when the legacy connecting UI is displayed.
v6.0 updates the SDK to AndroidX and thus apps using 6.0+ must support AndroidX and Target API Level 29+ (AndroidX is required for Target API Level 29+).
Play Console Target API Levels are described here. This states that Target API Level 29+ is required for new apps from Aug 3, 2020 and for app updates from Nov 2, 2020.
Migrating to AndroidX is described here.
To simplify things, the error StreamingException
has been renamed to NetworkException
, and the failures network_problem
and user_timeout
have been aggregated into it.
Since the FirebaseML face detector has been replaced by ML Kit, we have followed suit. This removes the dependency of registering with firebase to use this face detector, and in keeping we have renamed this library from iproov-firebase
to iproov-mlkit
.
v5.2.2 improves IProovException
s with subclasses and removes Reason
enum for convenience.
-
IProovException
has moved package fromcom.iproov.sdk
tocom.iproov.sdk.core.exception
-
Reason
enum replaced with Error string constants
-
- New subclasses of
IProovException
, which are also found incom.iproov.sdk.core.exception
, that encapsulate the new Error string constantsCameraException
CameraPermissionException
CaptureAlreadyActiveException
EncoderException
FaceDetectorException
LightingModelException
MultiWindowException
ServerException
StreamingException
UnsupportedDeviceException
There is a new item added to the Reason enum called CAPTURE_ALREADY_ACTIVE_ERROR
. The purpose of this error is to inform when the previous IProov is still running. The details are as follows:
- IProov will still be running, after its Activity has closed and the user is returned to the calling Activity, until a terminating event is sent through the
IProov.Listener
(such events are:onSuccess()
,onError()
,onCancelled()
andonFailure()
). - If
IProov.launch()
is called before such a terminating event thenonError()
will be called withReason.CAPTURE_ALREADY_ACTIVE_ERROR
.
The launch()
method in 5.0.0 which passed the listener as the final parameter has been deprecated in favor of a launch()
method without the listener. All other parameters remain the same, You should now register the listener with a call to IProov.registerListener(listener)
in your Activity onCreate()
method, and call IProov.unregisterListener()
in onDestroy()
. Consult the README for further details.
Options.ui.logoImage
has been removed and replaced with two new options:
-
Options.ui.logoImageResource
- pass a drawable resource ID -
Options.ui.logoImageDrawable
- pass a drawable directly
This has been a major revision.
- Tokens (logging in, enrolment and validation) no longer form part of the SDK
- You no longer need to use Intents (and ActivityResults)
- Android SDK 16-18 is NO LONGER supported. Now requires a minimum of Android SDK 19+ (v4.4 Kitkat).
- Options have changed
- How you launch iProov has been greatly simplified
For security reasons, the old three-step flow has been separated out. Logging in, enrolment and validation are now done via our API only. The SDK now only provides the scanner function. This allows for a more secure flow. You are expected to secure your apiKey and secret on your own API servers (and no longer have to ship them inside your app) behind suitable end points. There your servers will call our API when called upon by your app.
For convenience, and certainly NOT for production, we provide sample client api code to help you to test your app out before you have suitable server endpoints created. Indeed, the "Waterloo Bank" sample app uses this, so you can look at that for sample usage.
Note that if you are using Kotlin then the "Waterloo Bank" sample app demonstrates both Java and Kotlin for you to compare and contrast.
Intent i = new IProov.NativeClaim.Builder(actvity)
.setMode(IProov.Mode.Verify)
.setServiceProvider("{{api-key}}")
.setUsername("{{username}}")
.getIntent();
startActivityForResult(i, 0);
Note the new hierarchical structure of the options.
IProov.Options options = new IProov.Options();
options.ui.autoStartDisabled = false;
options.ui.logoImage = R.mipmap.ic_launcher;
options.ui.fontPath = "Merriweather-Bold.ttf";
IProov.launch(context, token, options, new IProov.Listener() {
@Override
public void onSuccess(String token) {
// Successfully registered (enrol) or iProoved (verify)
}
@Override
public void onFailure(String reason, String feedback) {
// Failed to registered (enrol) or iProoved (verify)
// This is usually due to lighting conditions or face movement
}
@Override
public void onProcessing( double progress, String message) {
// Scanning is in progress, providing a message/prompt/title for the user and a value 0.0 to 1.0 indicating how far through the process we are
}
@Override
public void onError(IProovException e) {
// An unrecoverable error occurred e.g. network problems. See IProovException.Reason.
}
@Override
public void onCancelled() {
// The user hit back or home and cancelled the scan
}
});
val options = new IProov.Options()
.apply {
ui.autoStartDisabled = false
ui.fontPath = "Merriweather-Bold.ttf"
ui.logoImage = R.mipmap.ic_launcher
}
IProov.launch(context, token, createOptions(), object : IProov.Listener {
override fun onSuccess(token: String) {
// Successfully registered (enrol) or iProoved (verify)
}
override fun onFailure(reason: String?, feedback: String?) {
// Failed to registered (enrol) or iProoved (verify)
// This is usually due to lighting conditions or face movement
}
override fun onProcessing(progress: Double, message: String) {
// Scanning is in progress, providing a message/prompt/title for the user and a value 0.0 to 1.0 indicating how far through the process we are
}
override fun onError(e: IProovException) {
// An unrecoverable error occurred e.g. network problems. See IProovException.Reason.
}
override fun onCancelled() {
// The user hit back or home and cancelled the scan
}
})
IProov.launch()
is overloaded: from the simplest with just the parameters: context
, token
and listener
, the next has those and adds options
also; and the full one which also adds a streamingUrl
.
Required
-
String baseURL;
- removed and added as an optional parameter to a connection
Optional
-
boolean autoStart = false;
-
String localeOverride = "";
-
boolean messageDisabled = false;
-
int startingBackgroundColor;
-
int startingEdgeColor;
-
int lowLightBackgroundColor;
- removed -
int lowLightEdgeColor;
- removed -
boolean enableScreenshots;
-
boolean enableRemoteLogging;
- removed -
String regularFont;
- removed -
String boldFont;
- removed -
boolean swapMessagePosition;
- removed -
int connectingOvalColor;
-
int notReadyOvalColor;
-
int readyOvalColor;
-
int logoImage;
-
int notificationImage;
- removed -
String notificationTitle;
- removed -
String pushToken;
- removed -
boolean pinningDisabled = false;
-
int[] certificateFiles;
-
int maxPitchAngle;
-
int maxYawAngle;
-
int maxRollAngle;
Optional
Under the ".ui" hierarchy:
-
Boolean autoStartDisabled
- was called autoStart and inverted in meaning -
String title;
- replaces messageDisabled, allowing title (message) to be changed, otherwise set by system if null -
Integer backgroundColor;
- was called startingBackgroundColor -
Integer lineColor;
- was called startingEdgeColor -
Integer loadingTintColor;
- was called connectingOvalColor -
Integer notReadyTintColor;
- was called notReadyOvalColor -
Integer readyTintColor;
- was called readyOvalColor Boolean enableScreenshots;
-
String fontAsset;
- was called regularFont (boldFont removed), from asset folder -
String fontResource;
- new resource based font method Integer logoImage;
-
Boolean scanLineDisabled;
- new, was under .capture -
Filter filter;
- new, one of {CLASSIC, SHADED, VIBRANT} -
Orientation orientation;
- new, one of {PORTRAIT, REVERSE_PORTRAIT, LANDSCAPE, REVERSE_LANDSCAPE}
Under the ".capture" hierarchy:
Integer maxPitchAngle;
Integer maxYawAngle;
Integer maxRollAngle;
-
Camera camera;
- new, select camera to use, FRONT or EXTERNAL (usb)
Under the ".network" hierarchy:
-
List<Integer> certificates;
- was called certificateFiles, was array -
Boolean disableCertificatePinning
- was called pinningDisabled -
Integer timeoutSecs;
- new, control over network -
String path;
- new, control over network
The following reasons no longer exist, because both registration and enrolment are no longer in the SDK: UNKNOWN_IDENTITY
, ALREADY_ENROLLED
. Also Reason codes have been consolidated and simplified overall.
public enum Reason {
GENERAL_ERROR, -- Removed, now handled by ENCODER_ERROR and STREAMING_ERROR
NETWORK_ERROR, -- Removed, now handled by ENCODER_ERROR and STREAMING_ERROR
STREAMING_ERROR,
UNKNOWN_IDENTITY,
ALREADY_ENROLLED, -- Removed, no longer handling fetching the token
USER_PRESSED_BACK, -- Removed, now handled by onCancelled()
USER_PRESSED_HOME, -- Removed, now handled by onCancelled()
UNSUPPORTED_DEVICE,
CAMERA_PERMISSION_DENIED,
SSL_EXCEPTION, -- Removed, now handled by STREAMING_ERROR
SERVER_ABORT; -- Renamed to SERVER_ERROR
}
public enum Reason {
ENCODER_ERROR,
STREAMING_ERROR,
UNSUPPORTED_DEVICE,
CAMERA_PERMISSION_DENIED,
SERVER_ERROR,
MULTI_WINDOW_MODE_UNSUPPORTED,
CAMERA_ERROR,
LIGHTING_MODEL_ERROR
}
NB: the UIOptions class has been renamed to IProovConfig. IProovConfig now also includes setPrivacyPolicyDisabled
, setInstructionsDialogDisabled
and setMessageDisabled
, which have been moved from NativeClaim.Builder
There are now some additional options available to customize the interface presented by the SDK. See the "Configuration Options" section of Readme for more info.
In SDK v3.1.0, we moved to explicit Intents with methods to build the Intent for you. We had feedback from users that they wanted more customisation options when creating an iProov request, so we have now moved to a builder-style approach for building the intent which allows a much greater degree of flexibility.
Intent i = IProov.newVerifyUsernameIntent(this, "{{api-key}}", "{{username}}");
startActivityForResult(i, 0);
Intent i = new IProov.NativeClaim.Builder(this)
.setMode(IProov.Mode.Verify)
.setServiceProvider("{{api-key}}")
.setUsername("{{username}}")
.getIntent();
startActivityForResult(i, 0);
Consult the documentation for the full set of builders and available options that they can accept.
Previously, iProov was launched by starting an Intent with the action IProov.INTENT_IPROOV
. We have now moved to using explicit Intents.
We have also taken this opportunity to simplify the process of launching iProov, so we provide a series of IProov.newIntent()
methods that builds the Intent for you, via a simple, clean API.
For further information, see the Launch Modes section. An example of the new approach versus the old one is as follows:
Intent i = new Intent(IProov.INTENT_IPROOV);
i.putExtra(IProov.EXTRA_MODE, IProov.Mode.Verify.ordinal());
i.putExtra(IProov.EXTRA_SERVICE_PROVIDER, "{{api-key}}");
i.putExtra(IProov.EXTRA_USERNAME, "{{username}}");
startActivityForResult(i, 0);
Intent i = IProov.newVerifyUsernameIntent(this, "{{api-key}}", "{{username}}");
startActivityForResult(i, 0);
The delivery of the iProov result to your Activity via onActivityResult()
is unchanged.
You are no longer required to explicitly initialise iProov with a call IProov.init(context)
before using iProov in your application, which was introduced in SDK v2.6.4.
You should remove any calls to IProov.init(context)
from your application.