Features¶
The Gini Capture SDK provides various features you can enable and configure. All of the features are configured during
creation of a new GiniCapture
instance. Specifically the GiniCapture.Builder
is used to configure the Gini
Capture SDK. It’s reference documentation
lists all the options.
Note
Some features require additional contractual aggreements and may not be used without prior confirmation. Please get in touch with us in case you are not sure which features your contract includes.
The following sections list all the features along with the related configuration options.
Document Capture¶
This is the core feature of the Gini Capture SDK. It enables your app to capture documents with the camera and prepares them to be analysed by the Gini Bank API.
Onboarding¶
The onboarding feature presents essential information to the user on how to best capture documents.
You can customize the onboarding in the following ways:
- Disable showing the onboarding at first run:
- By default the onboarding is shown at first run. To disable this pass
false
toGiniCapture.Builder.setShouldShowOnboardingAtFirstRun()
.
- Customize the onboarding pages:
- If you wish to show different onboarding pages then pass a list of
OnboardingPage
objects toGiniCapture.Builder.setCustomOnboardingPages()
.
- Force show the onboarding:
- If you wish to show the onboarding after the first run then pass
true
toGiniCapture.Builder.setShouldShowOnboarding()
.
Single Page¶
By default the Gini Capture SDK is configured to capture single page documents. No further configuration is required for this.
Important
If you integrate using the Component API you will need to launch the ReviewFragmentCompat
when the
CameraFragmentListener.onDocumentAvailable()
is invoked. See the Component API section for further details.
Multi-Page¶
The multi-page feature allows the SDK to capture documents with multiple pages.
To enable this simply pass true
to GiniCapture.Builder.setMultiPageEnabled()
.
Important
If you integrate using the Component API you will need to launch the MultiPageReviewFragment
when the
CameraFragmentListener.onProceedToMultiPageReviewScreen()
is invoked. See the Component API section for further details.
Camera¶
- Enable the flash toggle button:
- To allow users toggle the camera flash pass
true
toGiniCapture.Builder.setFlashButtonEnabled()
.
- Turn off flash by default:
- Flash is on by default and you can turn it off by passing
false
toGiniCapture.Builder.setFlashOnByDefault()
.
QR Code Scanning¶
By using the Google Mobile Vision API the SDK can read payment data from QR Codes. We support the BezahlCode , EPC069-12 (Stuzza (AT) and GiroCode (DE)) and EPS formats.
When a supported QR code is detected with valid payment data a popup is shown in the camera screen. The user may tap the popup to use the payment data directly without the need to analyse the document.
If the QR code does not have a supported payment format then a popup informs the user that a QR code was detected but it cannot be used.
After the user tapped on the QR code detected popup the payment information is extracted form the QR code. The result is
returned either in the result of the CameraActivity
(Screen API) or in the
CameraFragmentListener.onExtractionsAvailable()
method (Component API).
QR Code Scanning is available on devices running Android with Google Play Services installed.
To enable this feature simply pass true
to GiniCapture.Builder.setQRCodeScanningEnabled
.
Important
When your application is installed Google Mobile Services will download libraries to the device in order to do QR code detection. If another app already uses QR code detection on the device the library won’t be downloaded again. Under certain circumstances (user not online, slow connection or lack of sufficient storage space) the libraries will not be ready at the time your app starts the camera screen and QR code detection will be silently disabled until the next time the camera screen starts.
Document Import¶
This feature enables the Gini Capture SDK to import documents from the camera screen. When it’s enabled an additional button is shown next to the camera trigger. Using this button allows the user to pick either an image or a pdf from the device.
You can specify the document types the user will be able to select when enabling this feature. You can enable only images, only pdfs or both images and pdfs.
To enable it simply pass a DocumentImportEnabledFileTypes
enum value to
GiniCapture.Builder.setDocumentImportEnabledFileTypes()
.
Android Manifest¶
You need to declare the READ_EXTERNAL_STORAGE
permission in your app’s AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="...">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
If the permission has not been granted the Gini Capture SDK will prompt the user to grant the permission when they use the document import feature.
You will also need to declare that your app queries for apps that can handle intents to pick or open image and pdf documents (you can read more about package visibility filtering introduced in Android 11 here) :
<queries>
<intent>
<action android:name="android.intent.action.PICK" />
<data android:mimeType="image/*" />
</intent>
<intent>
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<data android:mimeType="image/*" />
</intent>
<intent>
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<data android:mimeType="application/pdf" />
</intent>
</queries>
Intercepting the imported document¶
You can intercept the imported document and deny the Gini Capture SDK from using it.
If you use the Screen API then you need to subclass the CameraActivity
and override the
onCheckImportedDocument
method. See it’s reference documentation
for details.
With the Component API you can intercept the document in the CameraFragmentListener.onCheckImportedDocument()
method. The method signature and usage is the same as above.
File Import (Open With)¶
The file import (or “open with”) feature allows importing of files from other apps via Android’s “open with” or “share” functionality.
Note
We are using the term file import
to refer to the “open with” feature within the Gini Capture SDK. From the
point of view of the SDK files are imported into the SDK from an outside source. It is not aware and cannot set
configuration related to enabling the client app to receive files via Android’s “open with” or “share”
functionality.
To enable it pass true
to GiniCapture.Builder.setFileImportEnabled()
.
In addition to enabling it your app needs to declare intent filters for receiving pdfs and/or images from other apps and then forward the incoming intent to the Gini Capture SDK.
Registering pdf and image file types¶
Add the following intent filter to the activity in your AndroidManifest.xml
you wish to receive incoming pdfs and
images:
<activity android:name=".ui.MyActivity">
<!-- Receiving images: -->
<intent-filter
android:label="@string/label_for_image_open_with">
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.SEND" />
<!-- The below SEND_MULTIPLE action is only needed if you enabled scanning of multi-page documents: -->
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<!-- Receiving pdfs: -->
<intent-filter
android:label="@string/label_for_pdf_open_with">
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/pdf" />
</intent-filter>
</activity>
Note
We recommend adding ACTION_VIEW to the intent filter to also allow users to send pdfs and images to your app from apps that don’t implement sharing with ACTION_SEND but enable viewing the pdf or file with other apps.
Handling Imported Files¶
When your app is requested to handle a pdf or an image your activity (declaring the intent filter shown above) is
launched or resumed (onNewIntent()
) with an Intent having ACTION_VIEW
or ACTION_SEND
.
We recommend checking whether the Intent has the required action before proceeding with it:
String action = intent.getAction();
if (Intent.ACTION_VIEW.equals(action) || Intent.ACTION_SEND.equals(action)) {
...
}
Screen API¶
Using the Screen API, create an Intent for launching the Gini Capture SDK with
GiniCapture.getInstance().createIntentForImportedFile()
or if you enabled scanning of multi-page documents
GiniCapture.getInstance().createIntentForImportedFiles()
. The first method will throw an
ImportedFileValidationException
, if the file was invalid and the latter will return the same exception in the
callback.
void startGiniCaptureSDKForImportedFile(final Intent importedFileIntent) {
// Configure the Gini Capture SDK first
configureGiniCapture();
if (GiniCapture.hasInstance() && GiniCapture.getInstance().isMultiPageEnabled()) {
mFileImportCancellationToken = GiniCapture.getInstance().createIntentForImportedFiles(
importedFileIntent, (Context) this,
new AsyncCallback<Intent, ImportedFileValidationException>() {
@Override
public void onSuccess(final Intent result) {
mFileImportCancellationToken = null;
startActivityForResult(result, REQUEST_SCAN);
}
@Override
public void onError(final ImportedFileValidationException exception) {
mFileImportCancellationToken = null;
handleFileImportError(exception);
}
@Override
public void onCancelled() {
mFileImportCancellationToken = null;
}
});
} else {
try {
final Intent giniCaptureIntent =
GiniCapture.createIntentForImportedFile(
importedFileIntent,
(Context) this, null, null);
startActivityForResult(giniCaptureIntent, REQUEST_SCAN);
} catch (final ImportedFileValidationException e) {
e.printStackTrace();
handleFileImportError(e);
}
}
}
void handleFileImportError(final ImportedFileValidationException exception) {
String message = ...
if (exception.getValidationError() != null) {
// Get the default message
message = getString(exception.getValidationError().getTextResource());
// Or use custom messages
switch (exception.getValidationError()) {
case TYPE_NOT_SUPPORTED:
message = ...
break;
case SIZE_TOO_LARGE:
message = ...
break;
case TOO_MANY_PDF_PAGES:
message = ...
break;
case PASSWORD_PROTECTED_PDF:
message = ...
break;
case TOO_MANY_DOCUMENT_PAGES:
message = ...
break;
}
}
new AlertDialog.Builder((Context) this)
.setMessage(message)
.setPositiveButton("OK", (dialogInterface, i) -> finish())
.show();
}
If scanning of multi-page documents is enabled then either the multi-page review screen or the analysis screen will be launched. PDFs cannot be reviewed by the user and in that case the analysis screen is launched directly. You should not expect the review screen to be launched every time.
When multi-page is disabled then the difference is only that the single-page review screen will be used instead.
Component API¶
For the Component API, create a Document
with with
GiniCapture.getInstance().createDocumentForImportedFile()
or if you enabled scanning of multi-page documents
GiniCapture.getInstance().createDocumentForImportedFiles()
. The first method will throw an
ImportedFileValidationException
, if the file was invalid and the latter will return the same exception in the
callback.
The ReviewFragment
or MultiPageReviewFragment
may only be used with reviewable documents. Therefore, it is important to
check whether the document is reviewable or not:
void startGiniCaptureSDKForImportedFile(final Intent importedFileIntent) {
// Configure the Gini Capture SDK first
configureGiniCapture();
if (GiniCapture.hasInstance() && GiniCapture.getInstance().isMultiPageEnabled()) {
mFileImportCancellationToken = GiniCapture.getInstance().createDocumentForImportedFiles(
importedFileIntent, (Context) this,
new AsyncCallback<Document, ImportedFileValidationException>() {
@Override
public void onSuccess(@NonNull final Document result) {
if (result.isReviewable()) {
launchMultiPageReviewScreen();
} else {
launchAnalysisScreen(result);
}
finish();
}
@Override
public void onError(
@NonNull final ImportedFileValidationException exception) {
handleFileImportError(exception); // same method as in the Screen API example
}
@Override
public void onCancelled() {
}
});
} else {
try {
final Document document = GiniCapture.createDocumentForImportedFile(
importedFileIntent, (Context) this);
if (document.isReviewable()) {
launchReviewScreen(document);
} else {
launchAnalysisScreen(document);
}
finish();
} catch (final ImportedFileValidationException e) {
e.printStackTrace();
handleFileImportError(e); // same method as in the Screen API example
}
}
}
Help Screen Customization¶
You can show your own help screens in the Gini Capture SDK. You can pass the title and activity for each screen to the
GiniCapture.Builder
using a list of HelpItem.Custom
objects:
List<HelpItem.Custom> customHelpItems = new ArrayList<>();
customHelpItems.add(new HelpItem.Custom(R.string.custom_help_screen_title,
new Intent((Context) this, CustomHelpActivity.class)));
GiniCapture.newInstance()
.setCustomHelpItems(customHelpItems)
.build();
You can also disable the supported formats help screen by passing false
to
GiniCapture.Builder.setSupportedFormatsHelpScreenEnabled()
.
Event Tracking¶
You have the possibility to track various events which occur during the usage of the Gini Capture SDK.
To subscribe to the events you need to implement the EventTracker
interface and pass it to the builder when creating
a new GiniCapture
instance:
GiniCapture.newInstance()
.setEventTracker(new MyEventTracker());
.build();
In MyEventTracker
you can handle the events you are interested in.
class MyEventTracker implements EventTracker {
@Override
public void onCameraScreenEvent(final Event<CameraScreenEvent> event) {
switch (event.getType()) {
case TAKE_PICTURE:
// handle the picture taken event
break;
case HELP:
// handle the show help event
break;
case EXIT:
// handle the exit event
break;
}
}
@Override
public void onOnboardingScreenEvent(final Event<OnboardingScreenEvent> event) {
(...)
}
@Override
public void onAnalysisScreenEvent(final Event<AnalysisScreenEvent> event) {
(...)
}
@Override
public void onReviewScreenEvent(final Event<ReviewScreenEvent> event) {
(...)
}
}
Note
If you use the Screen API all events will be triggered automatically.
If you use the Component API some events will not be triggered (for ex. events which rely on
Activity#onBackPressed()
). You can check in the table below whether all the events you are interested in are
triggered.
To manually trigger events just call the relevant method of your EventTracker
implementation with the required
event.
Events¶
Event types are partitioned into different domains according to the screens that they appear on. Each domain has a number of event types. Some events may supply additional details in a map.
API | Domain | Event enum value and details map keys | Comment | Introduced in (updated in) |
---|---|---|---|---|
Screen + Component | Onboarding | OnboardingScreenEvent.START |
Onboarding started | 1.0.0 |
Screen + Component | Onboarding | OnboardingScreenEvent.FINISH |
User completes onboarding | 1.0.0 |
Screen | Camera Screen | CameraScreenEvent.EXIT |
User closes the camera screen | 1.0.0 |
Screen | Camera Screen | CameraScreenEvent.HELP |
User taps “Help” on the camera screen | 1.0.0 |
Screen + Component | Camera Screen | CameraScreenEvent.TAKE_PICTURE |
User takes a picture | 1.0.0 |
Screen | Review Screen | ReviewScreenEvent.BACK |
User goes back from the review screen | 1.0.0 |
Screen + Component | Review Screen | ReviewScreenEvent.NEXT |
User advances from the review screen | 1.0.0 |
Screen + Component | Review Screen | ReviewScreenEvent.UPLOAD_ERROR
ReviewScreenEvent.UPLOAD_ERROR_DETAILS_MAP_KEY.MESSAGE
ReviewScreenEvent.UPLOAD_ERROR_DETAILS_MAP_KEY.ERROR_OBJECT |
Upload error in the review screen | 1.0.0 |
Screen | Analysis Screen | AnalysisScreenEvent.CANCEL |
User cancels the process during analysis | 1.0.0 |
Screen + Component | Analysis Screen | AnalysisScreenEvent.ERROR
AnalysisScreenEvent.ERROR_DETAILS_MAP_KEY.MESSAGE
AnalysisScreenEvent.ERROR_DETAILS_MAP_KEY.ERROR_OBJECT |
The analysis ended with an error. | 1.0.0 |
Screen + Component | Analysis Screen | AnalysisScreenEvent.RETRY |
The user decides to retry after an analysis error. | 1.0.0 |
The supported events are listed for each screen in a dedicated enum. You can view these enums in our reference documentation.
Error Logging¶
The SDK logs errors to the Gini Bank API when the default networking implementation is used (see the Default networking implementation section).
You can disable the default error logging by passing false
to GiniCapture.Builder.setGiniErrorLoggerIsOn()
.
If you would like to get informed of error logging events you can pass your implementation of the
ErrorLoggerListener
interface to GiniCapture.Builder
:
GiniCapture.newInstance()
.setCustomErrorLoggerListener(new MyErrorLoggerListener())
.build();