eSign PDFs with a Certificate on Android
This guide shows how Electronic Signatures and Digital Signatures can be used together.
To combine using the Electronic Signatures signing UI with digitally signing a document using a certificate, your activity needs to implement two interfaces: an OnSignaturePickedListener
, and a DocumentSigningListener
. The OnSignaturePickedListener
will allow you to override onSignaturePicked
, which can then be used to apply the created signature annotation to a digital signature. The DocumentSigningListener
will enable you to access the signed document once it has been saved, in case you need to display it.
It could look something like this:
class MyActivity : PdfActivity(), OnSignaturePickedListener, DocumentSigningListener { private var signatureFormFieldName: String? = null override fun onSignaturePicked(signature: Signature) { val document = document ?: return // Signature form name can be obtained from an `addOnFormElementClickedListener`. val signatureFormFieldName = this.signatureFormFieldName ?: return val formField = document.formProvider.getFormFieldWithFullyQualifiedName(signatureFormFieldName) // The signature object provides convenient conversion to ink or stamp annotation. val signatureAnnotation: Annotation = when (signature.annotationType) { AnnotationType.INK -> signature.toInkAnnotation( document, formField.formElement.pageIndex, formField.formElement.boundingBox) AnnotationType.STAMP -> signature.toStampAnnotation( document, formField.formElement.pageIndex, formField.formElement.boundingBox) else -> throw IllegalStateException("Unhandled Signature type. Neither Ink, nor Stamp.") } // Add the annotation to the document. This step is required so we can render the signature // to pass the render to the `SignatureAppearance`. document.annotationProvider.addAnnotationToPage(signatureAnnotation) val w = kotlin.math.abs(signatureAnnotation.boundingBox.width().toInt()) val h = kotlin.math.abs(signatureAnnotation.boundingBox.height().toInt()) val signatureBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888) signatureAnnotation.renderToBitmap(signatureBitmap) // Now that we've made the bitmap, we can remove the annotation from the document. document.annotationProvider.removeAnnotationFromPage(signatureAnnotation) // Now sign the document with a certificate asset in the next function. signDocumentWithSignatureBitmap(formField.formElement as SignatureFormElement, signatureBitmap) } private fun signDocumentWithSignatureBitmap(formElement: SignatureFormElement, signatureBitmap: Bitmap) { // The signer is a named entity holding a certificate (usually a person) and has a display // name shown in the app. val signer = Pkcs12Signer( "John Appleseed", Uri.parse("file:///android_asset/JohnAppleseed.p12") ) // We need to register the signer with the signature manager for signing to work. SignatureManager.addSigner("john_appleseed", signer) // Provide a password to the signer, which will be used to unlock its private key. if (signer is InteractiveSigner) { (signer as InteractiveSigner).unlockPrivateKeyWithPassword("password") } // Add the created signature to the appearance. val signatureAppearance = SignatureAppearance.Builder() .setShowWatermark(false) .setSignatureGraphic(SignatureAppearance.SignatureGraphic.fromBitmap(getImageUri(signatureBitmap))) .build() // Show the signer dialog that handles the signing process. SignatureSignerDialog.show( supportFragmentManager, SignatureSignerDialog.Options.Builder(document!!, formElement.formField, signer) .signatureAppearance(signatureAppearance) .build(), this ) } override fun onDocumentSigned(signedDocumentUri: Uri) { // Replace the loaded document with the signed document. setDocumentFromUri(signedDocumentUri, null) } }
You can see a working Catalog example of this code here.