Getting started
The PdfViewer is a standard view that can be inserted in your activity's layout :
<ch.sysmosoft.sense.smartcontract.sdk.wysiwys.PdfViewer
android:id="@+id/pdfViewer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>The reference to the PdfViewer can be retrieved after the layout was inflated :
PdfViewer pdfViewer = findViewById(R.id.pdfViewer);The WYSIWYS SDK has to be initialized prior using any provided method.
PdfViewerConfiguration configuration = PdfViewerConfiguration.builder()
.licence(WYSIWYS_LICENCE)
.storageKey(STORAGE_KEY)
.username(mUsername)
.build();
PdfViewer.initialize(context, configuration);- The
WYSIWYS_LICENCEis a licence key provided by Sysmosoft for a unique package name. - The
STORAGE_KEYis a 16 bytes long key that will be used to encrypt data on the device. This key must not be stored in an unsecured storage or hardcoded in the app. It might be derived from a user's input, or securely stored using Android Keystore API. - The username represents the user that will sign document. It is used to retrieve a signature field dedicated to the user.
Opening a document
ViewerConfiguration viewerConfiguration = new ViewerConfiguration();
viewerConfiguration.setDocumentEventListener(this);
viewerConfiguration.setVerticalScrolling(true);
SignatureConfiguration signatureConfiguration = new SignatureConfiguration();
signatureConfiguration.setSignatureEventListener(this);
signatureConfiguration.setSignatureAppearance(signatureAppearance);
signatureConfiguration.setWatermarkAppearance(watermarkAppearance);
pdfViewer.openDocument(context, inputStream, documentId, signatureConfiguration);When opening a document, the following arguments must be provided :
- The reference to the
FragmentActivityhosting the view - An
InputStreamwhere the document can be read. - An ID that is identifying the document
- The
ViewerConfigurationconfiguration :- The
DocumentEventListeneris an interface to listen events related to the document (loading, page change, etc.) emitted by the SDK. - The
verticalScrollingflag to specify whether the scrolling is vertical or horizontal - The
continuousScrollingflag to specify whether the scrolling is continuous or page per page
- The
- The
SignatureConfigurationconfiguration :- The
SignatureEventListeneris an interface to listen events related to the signature emitted by the SDK. - The
SignatureAppearanceis the configuration of the visual signature. - The
SignatureAttributesis the configuration of the digital signature attributes. - The
WatermarkAppearanceis the configuration of the watermark that will be applied on top of each page of a refused document.
- The
The document will be loaded asynchronously in the view and the event DocumentEventListener#onDocumentLoaded()
is sent once the document is displayed.
Form documents with standard inputs can be edited directly by the user and all its modifications are automatically saved.
Reopening a document
The user has many reasons to be interrupted while editing a document. After being opened, a document remains in progress and all modifications are automatically saved in an secured internal storage.
It's possible to know if a document is in progress using the method below :
PdfViewer.isDocumentInProgress(documentId)It's possible to reopen the document using the PdfViewer#reopenDocument method that takes the same arguments except the input stream that is not needed.
ViewerConfiguration viewerConfiguration = new ViewerConfiguration();
viewerConfiguration.setDocumentEventListener(this);
viewerConfiguration.setVerticalScrolling(true);
SignatureConfiguration signatureConfiguration = new SignatureConfiguration();
signatureConfiguration.setSignatureEventListener(this);
pdfViewer.reopenDocument(context, documentId, viewerConfiguration, signatureConfiguration);The document will be loaded asynchronously in the view and the event DocumentEventListener#onDocumentLoaded()
is sent once the document is displayed.
If a document in progress is reopened using the PdfViewer#openDocument method, it will be replaced by the document read from the input stream, losing all previous modifications.
Accepting / Refusing a document
Once a document is opened. It can be either accepted or refused.
pdfViewer.acceptDocument();
pdfViewer.refuseDocument();When accepting a document, the signature flow might differ depending the document to be signed (see previous section).
When refusing a document, a watermark will be applied on each page and the document will be signed with an invisible signature. Signing refused documents might not be needed depending the use case of the app.
If the document is visually modified (when refused or when at least one empty signature field is present),
the user has to confirm the signature of the updated document. A preview of the document will be shown to the user and the event SignatureEventListener#onConfirmationRequired() is emitted.
The app must call the following method to confirm the signature :
pdfViewer.confirmSignature();The preview will not be displayed for document that are not visually modified during signature (document without empty signature field).
The event SignatureEventListener#onPreparingDocument() is emitted when starting to prepare the document, allowing the app to display a loading indicator.
Once the document is prepared for signature, the event SignatureEventListener#onDocumentPreparedForSignature(byte[] documentDigest) is emitted.
The documentDigest received must be signed and then inserted into a PKCS#7 detached signature.
This signature can be generated client-side or using a remote signature API.
The document digest is unique to the signature request. The signature generated can be only embedded into the document currently opened. The digest is invalidated as soon a document is opened or reopened.
As of today, the SDK supports only the RSA signing algorithm with SHA-256 hashing algorithm.
pdfViewer.embedSignature(signature);- The signature is a valid PKCS#7 detached signature, generated for the given documentDigest
The last event SignatureEventListener#onProcessFinished(String reason, byte[] document) is then emitted with the signed document.
The SDK provides also a static method to embed the signature without the need to have a PdfViewer displayed. It allows the application to embed the signature from a background task or from a different view.
PdfViewer.embedSignature(context, documentId, signature, signatureEventListener);When a document is not going to be reopened anymore, the app must explicitly dispose the document.
PdfViewer.disposeDocument(documentId);Saving a document
The SDK automatically save the document when it is being accepted (acceptDocument()) or refused (refuseDocument()).
It's possible to force the saving of the document by calling the method saveDocument().
PdfViewer.saveDocument();Documents with required fields
The SDK verifies that a document containing required fields is completed before being accepted.
If the document is accepted using the pdfViewer#acceptDocument() method but a required field is empty,
the event SignatureEventListener#onMissingRequiredFormField is emitted and the document must be accepted again once all the required fields are filled.
Documents no empty signature field
If a document does not contain any empty signature field, the SDK lets the user positioning the signature in the current page.
When this situation occurs, the event SignatureEventListener#onSignatureRequiresPositioning() is emitted directly after calling pdfViewer#acceptDocument().
The user's signature is added to the document and user is able to resize and move it to the desired position.
The app is responsible to notify the user that the user has to move & resize the signature. Once the signature is correctly positioned, the app must call the API pdfViewer#onSignaturePositioned().
It's possible to cancel the current mode and ask the user to restore the edition mode by calling the method pdfViewer#cancelSignaturePositioning.
Documents with multiple signature fields
If a document contains multiple empty signature fields, the SDK lets the user deciding which field is the most appropriate for him.
When this situation occurs, the event SignatureEventListener#onSelectSignatureFormField() is emitted directly after calling pdfViewer#acceptDocument().
The viewer will scroll the document to the first available signature field and enable the field selection.
The app is responsible to notify the user that he has to click on a signature field.
Once selected, the app is notified with the SignatureEventListener#onSignatureFormFieldSelected() event and the process continues as if a single field was present.
If the document contains multiple empty signature fields but one of them has its name property that match the configured username in the SDK, this field will be automatically selected.
Customizing visual signatures
The configuration class SignatureAppearance offers different possibilities to customize the visual signature :
handwrittenSignatureEnabled: Enable handwritten signature. When enabled, the user will have to draw its signature or pick one if multiple are available.signerName: The text to be shown as visual signature if thehandwrittenSignatureEnabledis disabledsignerNameTypeFace: The typeface to use to draw the visual signature (default : default OS bold typeface)signerNameFontSize: The font size for the signer name (default : 48)dateTimePattern: The pattern to use to format the signature date (default:yyyy-MM-dd HH:mm:ss)dateTimeTypeFace: The typeface to use to draw the signature date (default : default OS typeface)dateTimeFontSize: The font size for the signature date (default : 28)signatureDescription: An optional description to be displayed in the signature field.signatureDescriptionTypeFace: The typeface to use to draw the signature description (default : default OS bold typeface)signatureDescriptionFontSize: The font size for the signature description (default : 28)signatureGraphic: The graphic that will be displayed in the bottom of the signatureinvisibleSignature: The digital signature will be applied on a new invisible signature field (default : false)
For a better signature resolution, the font sizes can be enlarged and the signature graphic increased accordingly. The signature will be correctly rendered for the user regardless of the font size.
Visual signatures provider
By default, the SDK provides an implementation to securely store visual signatures in a local database. You can define your own visual signature provider by implementing the delegate WYSSignatureStore and setting it through the method WYSPdfViewerConfiguration.signatureStore. The following methods must be implemented:
This method will be called when a new signature has been added. Two modes are available: WYSVisualSignatureModeDraw when the user has drawn its signature and WYSVisualSignatureModeImage when the user has uploaded an image.
WYSSignatureStore#addSignature:(UIImage *)signature capturedWithMode:(WYSSignatureMode)mode:
This method will be called wiht the signature id when the user has removed a signature.
WYSSignatureStore#removeSignature:(NSString *)identifier
This method must return a dictionnary of signature id (NSString) / signature image (UIImage).
WYSSignatureStore#signatures
Customizing digital signature attributes
The configuration class SignatureAttributes offers different possibilities to customize the attributes of the digital signature :
signatureName: Set the name attribute of the signature. It is sometimes displayed in the signature details of some PDF Viewer, but usually only the CN of the certificate is displayed. Default : The username provided in PdfViewerConfiguration.signatureLocation: Set thelocationattribute of the signature.signatureReason: Set the reason attribute of the signature. Default :acceptedorrefused, depending the user's decision.estimatedSignatureSize: Set the estimated size of the digital signature in bytes. It must not be lower than the actual signature size. Default : 32768 (32KB)
Customizing watermark
The configuration class WatermarkAppearance offers different possibilities to customize the visual appearance of the watermark :
title: Set the short title that will be displayed as watermark on refused documenttitleTypeFace: The typeface to use to draw the titletitleTypeFontSize: The font size for the title (default : 80)dateTimePattern: The pattern to use to format the watermark date (default:yyyy-MM-dd HH:mm:ss)dateTimeTypeface: The typeface to use to draw the datedateTimeFontSize: The font size for the date (default : 25)rotation: The rotation in degrees of the watermark (default 0)
Showing a document (read only)
This method can be used to simply display a document as it is. No signature process will be enabled.
The document is securely encrypted in the application's cache directory and removed automatically when the activity hosting the view is destroyed.
PdfViewer.showDocument(mFragmentActivity, inputStream, viewerConfiguration);Retrieving document info
When a document is loaded, the following information are available:
- Page count : Retrieves the number of pages in the document with the API
pdfViewer.getPageCount() - Page index : Retrieves the current page index of the document with the API
pdfViewer.getPageIndex()
When the user is scrolling to another page, the application can be informed by listening to the event DocumentEventListener#onPageChanged(int).
Managing handwritten signatures
Visual signatures applied in a signature field are automatically handled by the SDK :
- When there is no signature in the storage, the user is prompted to draw its signature
- When there is a single signature in the storage, it is automatically applied in the storage
- When there are multiple signatures in the storage, the user is prompted to select a signature.
In order to let the possibility to the user to add a second signature or to manage its existing signatures, a signature settings view can be opened.
PdfViewerActivity.showSignatureSettings(mFragmentActivity);