{"id":25553790,"url":"https://github.com/docusign/mobile-android-sdk","last_synced_at":"2025-04-09T13:11:17.012Z","repository":{"id":41351851,"uuid":"271858855","full_name":"docusign/mobile-android-sdk","owner":"docusign","description":"The Official Docusign Android SDK for integrating e-signature \u0026 signing documents. Click the link below to view SDK API Documentation https://docusign.github.io/mobile-android-sdk/","archived":false,"fork":false,"pushed_at":"2025-02-06T23:04:58.000Z","size":414894,"stargazers_count":18,"open_issues_count":0,"forks_count":12,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-02T12:07:56.438Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/docusign.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-12T17:52:28.000Z","updated_at":"2025-02-06T23:03:25.000Z","dependencies_parsed_at":"2024-01-18T22:57:56.676Z","dependency_job_id":"3915f561-5a58-49d5-bee6-4f8004c806f8","html_url":"https://github.com/docusign/mobile-android-sdk","commit_stats":null,"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fmobile-android-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fmobile-android-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fmobile-android-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fmobile-android-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/docusign","download_url":"https://codeload.github.com/docusign/mobile-android-sdk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248045246,"owners_count":21038554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-20T12:01:39.376Z","updated_at":"2025-04-09T13:11:16.981Z","avatar_url":"https://github.com/docusign.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Docusign Android SDK Integration\nDocusign Android SDK provides the following features:\n* Templates \n* Envelope creation\n* Offline Signing and Online Signing of documents\n* Syncing signed documents with Docusign\n\n## Credentials Needed\nBefore getting started, an Integration Key and valid Service User credentials are needed. The SDK cannot be used without these.\n### Integration Key\nTo use any Docusign SDK or the REST API, an Integration Key is needed. Visit https://developers.docusign.com/ to obtain an Integration Key if one does not already exist. Note that an Integration Key is first provisioned on the DEMO environment, and then must be promoted to PROD when ready. \n### Email \u0026 Password\nTo use the Docusign Android SDK, credentials are necessary. That user's credentials are what should be used in the Authentication section below.\n## Supported versions\nAndroid Studio version should be 3.4 and above. Apps which integrate with Docusign SDK requires AndroidX.\ncompileSdkVersion and targetSdkVersion should be 29 and above.\nDocusign SDK supports android versions 6.0 and above (API level 24).\n## Setup \n1.  In your application's root build.gradle file:\n\n    ```gradle\n    allprojects {\n        repositories {\n            google()\n            jcenter()\n    \n            maven {\n                url  \"https://docucdn-a.akamaihd.net/prod/docusignandroidsdk\"\n            }\n        }\n        }\n    ```\n\n    ### Docusign SDK Components \n    #### Online Signing   \n\n    If you would like to use Online Signing, add the following dependencies in your app's build.gradle file:\n\n    ```gradle\n        \n        dependencies {\n            implementation 'com.docusign:androidsdk:2.0.1'\n            implementation 'com.docusign:sdk-common:2.0.1'\n        }\n        \n    ```\n\n    #### Offline Signing  \n\n    If you would like to use Offline Signing, add the following dependencies in your app's build.gradle file:\n\n    ```gradle\n        \n        dependencies {\n            implementation 'com.docusign:androidsdk:2.0.1'\n            implementation 'com.docusign:sdk-common:2.0.1'\n            implementation 'com.docusign:sdk-offline-signing:2.0.1'\n        }\n    ```\n\n    #### eSign REST API\n\n    If you would like to access eSign REST API from SDK, add the following dependencies in your app's build.gradle file:\n\n    ```gradle\n    dependencies {\n        implementation 'com.docusign:androidsdk:2.0.1'\n        implementation 'com.docusign:sdk-common:2.0.1'\n        implementation 'com.docusign:sdk-esign-api:2.0.1'\n    }\n    ```\n\n2. If using CDN (as mentioned in the above steps) is not an option for downloading Docusign Android SDK, then you can download SDK manually as separate library. The SDK is available at [release](https://github.com/docusign/mobile-android-sdk/tree/master/release).  \n\n    In the app's build.gradle, add the following dependencies:\n    ```gradle\n    dependencies {\n        implementation fileTree(dir: 'libs', include: ['*.*'])\n    \n        implementation 'io.reactivex.rxjava2:rxjava:2.2.9'\n        implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'\n    \n        implementation 'android.arch.lifecycle:viewmodel:1.1.1'\n        implementation 'android.arch.lifecycle:extensions:1.1.1'\n    \n        implementation 'androidx.room:room-runtime:2.2.5'\n        implementation 'androidx.room:room-rxjava2:2.2.5'\n    \n        implementation 'androidx.work:work-runtime:2.3.4'\n        implementation 'androidx.work:work-rxjava2:2.3.4'\n    \n        implementation 'androidx.appcompat:appcompat:1.1.0'\n        implementation 'androidx.recyclerview:recyclerview:1.1.0'\n        implementation 'androidx.preference:preference-ktx:1.1.1'\n        implementation 'com.android.support:design:28.0.0'\n        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'\n        implementation 'jp.wasabeef:richeditor-android:1.2.2'\n        implementation 'com.edmodo:cropper:2.0.0'\n        implementation 'androidx.multidex:multidex:2.0.1'\n        implementation 'org.apache.commons:commons-lang3:3.4'\n        implementation 'io.gsonfire:gson-fire:1.8.0'\n        implementation 'io.swagger:swagger-annotations:1.5.18'\n        implementation 'commons-codec:commons-codec:1.10'\n        implementation 'com.squareup.okhttp3:okhttp:3.8.0'\n        implementation 'com.squareup.okio:okio:2.2.2'\n        implementation 'com.google.code.gson:gson:2.8.5'\n        implementation 'org.slf4j:slf4j-api:1.7.22'\n        implementation 'org.threeten:threetenbp:1.3.5'\n    \n        implementation 'com.squareup.retrofit2:retrofit:2.4.0'\n        implementation 'com.squareup.retrofit2:converter-gson:2.4.0'\n        implementation 'com.squareup.retrofit2:converter-scalars:2.4.0'\n        implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'\n    }\n    ```\n3. Sync Gradle and/or build your application\n4. If app release builds has minifyEnabled true, then go through the following:\n\n   In the app, if Gradle Plugin version is \u003e= 3.4.0, then the build system uses R8 for app size shrinking. Otherwise it uses ProGuard for app size shrinking.   \n   \n   If using ProGuard, make sure the Proguard version is \u003e= 6.1.1. \n   If Proguard version is \u003c 6.1.1, then you can include the Proguard as follows in your gradle build script:\n   ```gradle\n    build-script {\n        dependencies {\n          classpath 'com.android.tools.build:gradle:3.3.1'\n          classpath 'net.sf.proguard:proguard-gradle:6.1.1'\n        }\n    }\n   ```\n\n   For ProGuard and R8, make sure the gradle build script as follows:\n\n   ```gradle\n    android {\n        buildTypes {\n\t        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }   \n    ```\n\n   For ProGuard and R8, add the following ProGuard rules:\n\n    ```\n    -keepattributes Signature, InnerClasses, EnclosingMethod\n\n    #Retrofit does reflection on method and parameter annotations.\n    -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations\n\n    #Retain service method parameters when optimizing.\n    -keepclassmembers,allowshrinking,allowobfuscation interface * {\n     @retrofit2.http.* \u003cmethods\u003e;\n    }\n\n   #Ignore annotation used for build tooling.\n   -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement\n\n   #Ignore JSR 305 annotations for embedding nullability information.\n   -dontwarn javax.annotation.**\n\n   #Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.\n   -dontwarn kotlin.Unit\n\n   #Top-level functions that can only be used by Kotlin.\n   -dontwarn retrofit2.KotlinExtensions\n   -dontwarn retrofit2.KotlinExtensions$*\n\n   #With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy\n   #and replaces all potential values with null. Explicitly keeping the interfaces prevents this.\n   -if interface * { @retrofit2.http.* \u003cmethods\u003e; }\n   -keep,allowobfuscation interface \u003c1\u003e\n\n   #Optional third party libraries. You can safely ignore those warnings.\n   -dontwarn com.squareup.okhttp.**\n   -dontwarn com.squareup.picasso.**\n   -dontwarn com.edmodo.cropper.**\n   -dontwarn org.slf4j.impl.**\n\n   #RxJava needs these two lines for proper operation.\n   -keep class rx.internal.util.unsafe.** { *; }\n   -keep class com.google.**\n   -dontwarn com.google.**\n   -dontnote com.google.**\n\n   -keep class okhttp3.**\n   -dontwarn okhttp3.**\n   -dontnote okhttp3.**\n\n   -keep class retrofit2.**\n   -dontwarn retrofit2.**\n   -dontnote retrofit2.**\n\n   -keepnames class rx.android.schedulers.AndroidSchedulers\n   -keepnames class rx.Observable\n   -keep class rx.schedulers.Schedulers {\n     public static \u003cmethods\u003e;\n     public static ** test();\n    }\n    -keep class rx.schedulers.ImmediateScheduler {\n      public \u003cmethods\u003e;\n   }\n   -keep class rx.schedulers.TestScheduler {\n    public \u003cmethods\u003e;\n   }\n\n   -keep class rx.subscriptions.Subscriptions {\n     *;\n   }\n   -keep class rx.exceptions.** {\n     public \u003cmethods\u003e;\n   }\n   -keep class rx.subjects.** {\n     public \u003cmethods\u003e;\n   }\n\n   -keepclassmembers class android.webkit.** { *; }\n   -keep class android.webkit.** { *; }\n\n   #JavaScript rules and classes required to be kept\n   -keepclasseswithmembers class * {\n      @android.webkit.JavascriptInterface \u003cmethods\u003e;\n   }\n\n   -keepclasseswithmembernames class * {\n      native \u003cmethods\u003e;\n   }\n\n   -keepclassmembers class com.docusign.androidsdk.** { *; }\n   -keep class com.docusign.androidsdk.** { *; }\n\n   -keepclassmembers class com.docusign.esign.** { *; }\n   -keep class com.docusign.esign.** { *; }\n\n   -dontwarn kotlinx.coroutines.**\n   -keep class kotlinx.coroutines.** { *; }\n    ```\n\n## API Documentation\nRefer to Docusign SDK api documentation at https://docusign.github.io/mobile-android-sdk/\n\n\n## Initialization\nIn your application's Application class:\n```java\nDocusign.init(\n    this, // the Application Context\n    \"[YOUR INTEGRATION KEY HERE]\", // recommend not hard-coding this\n    DSMode.DEBUG // this controls the logging (logcat) behavior\n);\n```\n\n### Initialization for OAuth Login\nIn your application's Application class:\n```java\nDocusign.init(\n     this, // the Application Context\n     \"[YOUR INTEGRATION KEY HERE]\", // Same as Client Id\n     \"[YOUR CLIENT SECRET KEY]\",\n     \"[YOUR REDIRECT_URI]\",\n     DSMode.Debug  \n);\nDocusign.getInstance().setEnvironment(DSEnvironment.DEMO_ENVIRONMENT); // For Demo environment. For production environment, use DSEnvironment.PRODUCTION_ENVIRONMENT\n```\n\n## Authentication\n### Login\n#### OAuth\nAuthenticates the Docusign user using OAuth.\n```java\n// requestCode - This code will be returned in onActivityResult() of the calling activity\ntry {\n    DSAuthenticationDelegate docusignAuthDelegate = Docusign.getInstance().getAuthenticationDelegate();\n    docusignAuthDelegate.login(requestCode, context,\n        new DSAuthenticationListener() {\n            @Override\n            public void onSuccess(@NonNull DSUser user) {\n                // TODO: handle successful authentication here\n            }\n \n            @Override\n            public void onError(@NonNull DSAuthenticationException exception) {\n                // TODO: handle authentication failure here\n            }\n        }\n    );\n} catch (DocusignNotInitializedException exception) {\n    // TODO: handle error. This means the SDK object was not properly initialized\n}\n```\n\n#### AuthToken\nAuthenticates the Docusign user with the provided authToken and optional refreshToken.\n```java\n// accessToken - Access Token which authenticates the user\n// refreshToken - If the access token can be refreshed, the refresh token. Optional\n// expiresIn - The number of seconds from the time the access token was provisioned to when it will expire\ntry {\n    DSAuthenticationDelegate docusignAuthDelegate = Docusign.getInstance().getAuthenticationDelegate();\n    docusignAuthDelegate.login(accessToken, refreshToken, expiresIn, context,\n        new DSAuthenticationListener() {\n            @Override\n            public void onSuccess(@NonNull DSUser user) {\n                // TODO: handle successful authentication here\n            }\n \n            @Override\n            public void onError(@NonNull DSAuthenticationException exception) {\n                // TODO: handle authentication failure here\n            }\n        }\n    );\n} catch (DocusignNotInitializedException exception) {\n    // TODO: handle error. This means the SDK object was not properly initialized\n}\n```\n\n### Logout\nLogout the authenticated Docusign user.\n```java\n// Clears the Docusign cached data\nBoolean clearCachedData = true\n \ntry {\n    DSAuthenticationDelegate docusignAuthDelegate = Docusign.getInstance().getAuthenticationDelegate();\n    authenticationDelegate.logout(this, clearCachedData, new DSLogoutListener() {\n     @Override\n      public void onSuccess() {\n         // TODO: handle successful logout here\n      }\n \n     @Override\n     public void onError(@NonNull DSAuthenticationException e) {\n        // TODO: handle logout failure here\n     }\n});\n} catch (DocusignNotInitializedException exception) {\n    // TODO: handle error. This means the SDK object was not properly initialized\n}\n```\n\n## Templates\n### Get Templates\nRetrieves the list of templates.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\nDSTemplatesFilter filter = DSTemplatesFilter(count, null, null, startPosition);\n// count is no. of templates to be retrieved\n// startPosition is the startPosition/index of the templates retrieval.\ntemplateDelegate.getTemplates(filter, new DSTemplateListListener() {\n    @Override\n        public void onStart() {\n            // TODO: Handle when the templates retrieval process is started\n    }\n     \n    @Override\n    public void onComplete(DSTemplates templates) {\n            // TODO: Handle templates that are retrieved   \n        }\n     \n    @Overridee\n    public void onError(DSTemplateException exception) {\n        // TODO: Handle error when there is an exception while retrieving templates\n    }\n);\n```\n\n### Retrieve Downloaded Templates\nRetrieves the list of downloaded templates.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\ntemplateDelegate.retrieveDownloadedTemplates(new DSTemplateListListener() {\n    @Override\n        public void onStart() {\n            // TODO: Handle when retrieval of downloaded templates process is started\n    }\n     \n    @Override\n    public void onComplete(DSTemplates templates) {\n            // TODO: Handle downloaded templates that are retrieved\n        }\n     \n    @Override\n    public void onError(DSTemplateException exception) {\n        // TODO: Handle error when there is an exception while retrieving downloaded templates\n    }\n});\n```\n\n### GetTemplate\nFetches the template.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\ntemplateDelegate.getTemplate(templateId, null, new DSTemplateListener(){\n    @Override\n    public void onComplete(DSTemplateDefinition template) {\n        // TODO: Handle template that is retrieved\n    }\n \n    @Override\n    public void onError(DSTemplateException exception) {\n        // TODO: Handle error when there is an exception while retrieving the template\n    }\n});\n```\n\n### CacheTemplate\nCaches the template.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\ntemplateDelegate.cacheTemplate(templateId, new DSCacheTemplateListener(){\n    @Override\n    public void onStart() {\n        // TODO: Handle when caching of template proves is started\n    }\n \n    @Override\n    public void onComplete(DSTemplate template) {\n        // TODO: Handle template that is cached\n    }\n     \n    @Override\n    public void onError(DSTemplateException exception) {\n        // TODO: Handle error when there is an exception while caching the template\n    }  \n});\n```\n\n### RetrieveCachedTemplate\nRetrieves the cached template.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\ntemplateDelegate.retrieveCachedTemplate(templateId, new DSGetCachedTemplateListener(){\n    @Override\n    public void onComplete(DSTemplateDefinition template) {\n        // TODO: Handle cached template\n    }\n \n    @Override\n    public void onError(DSTemplateException exception) {\n        // TODO: Handle error when there is an exception while retrieving cached template\n    }\n});\n```\n\n### RemoveCachedTemplate\nRemoves the cached template.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\n// DSTemplateDefinition template. Refer to javadoc for more info about DSTemplateDefintion.\ntemplateDelegate.removeCachedTemplate(template, new DSRemoveTemplateListener(){\n    @Override\n    public void onTemplateRemoved(boolean isRemoved) {\n        // TODO: Handle when the template has been removed.\n    }\n});\n```\n\n### UseTemplate\n#### UseTemplate Offline\nUse the template and completes offline signing.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\ntemplateDelegate.useTemplateOffline(\n                context,\n                templateId,\n                envelopeDefaults, // This can be used to pre-fill the template values such as recipients, emails, tabs etc. Refer to javadoc for more info about DSEnvelopeDefaults.\n                pdfFileUri, // PDF file to append to the beginning or end of resulting envelope\n                insertPdfAtPosition,  // Whether to insert the PDF at the beginning or end\n                new DSOfflineUseTemplateListener() {\n                    @Override\n                    public void onComplete(@NotNull String envelopeId) {\n                        // TODO: Handle when the template has been successfully signed.\n                    }\n                     \n                    @Override\n                    public void onError(@NotNull DSTemplateException exception) {\n                        // TODO: Handle error when there is an exception while using the template or during signing\n                    }\n \n                    @Override\n                    public void onCancel(@NotNull String templateId, String envelopeId) {\n                        // TODO: Handle when the signing ceremony is cancelled\n                    }\n                });\n```\n\n#### UseTemplate Online\nUse the template and completes online signing.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\ntemplateDelegate.useTemplateOnline(\n        context,\n        templateId,\n        envelopeDefaults, // This can be used to pre-fill the template values such as recipients, emails, tabs etc. Refer to javadoc for more info about DSEnvelopeDefaults.\n        new DSOnlineUseTemplateListener() {\n            @Override\n            public void onComplete(@NotNull String envelopeId, boolean onlySent) {\n                // TODO: Handle when the online signing ceremony for all signers has been successful\n            }\n\n            @Override\n            public void onStart(String envelopeId) {\n                // TODO: Handle when the online signing is started\n            }\n\n            @Override\n            public void onRecipientSigningSuccess(String envelopeId, String recipientId) {\n                // TODO: Handle when the online signing success for a signer is successful\n            }\n\n            @Override\n            public void onRecipientSigningError(String envelopeId, String recipientId, DSTemplateException exception) {\n                // TODO: Handle when the error occurred during online signing for a signer\n            }\n                \n            @Override\n            public void onCancel(String envelopeId, String recipientId) {\n                // TODO: Handle when the online signing ceremony is cancelled\n            }\n\n            @Override\n            public void onError(String envelopeId, DSTemplateException exception) {\n                // TODO: Handle when the error occurred during online signing ceremony\n            }\n        });\n```\n\n### UpdateTemplate\nUpdates the cached template.\n```java\nDSTemplateDelegate templateDelegate = Docusign.getInstance().getTemplateDelegate();\ntemplateDelegate.updatedCachedTemplate(templateId, new DSUpdateCachedTemplateListener(){\n    @Override\n    public void onComplete(DSTemplate template, Boolean updateAvailable) {\n        // TODO: Handle when template is updated\n    }\n     \n    @Override\n    public void onError(DSTemplateException exception) {\n        // TODO: Handle error when there is an exception while updating the template\n    }\n});\n```\n\n### Templates usage scenario\n1. Get the list of templates with getTemplates\n2. Get a specific template with getTemplate\n3. Decide to save it locally with cacheTemplate\n4. Can list all cached/downloaded templates with retrieveDownloadedTemplates\n5. Can access a specific cached template with retrieveCachedTemplate\n6. Can clear the template from the cache with removeCachedTemplate\n7. Can update a cached template with updatedCachedTemplate\n\n## Envelope Creation\nThe following example shows how to build an Envelope with one document, two signer recipients and one CC recipient. Each signer recipient has one signature tab. It also includes some metadata. \n```java\ntry {\n            DSUser user = Docusign.getInstance().getAuthenticationDelegate().getLoggedInUser(context);\n            DSEnvelope  envelope = new DSEnvelope.Builder()\n                    .envelopeName(\"[ENVELOPE NAME HERE]\")\n                    .document(new DSDocument.Builder()\n                            .documentId(\"1\")\n                            .uri(\"file://path_to_your_pdf_file_here\")\n                            .name(\"[DOCUMENT NAME HERE]\")\n                            .build())\n                    .recipient(new DSEnvelopeRecipient.Builder()\n                            .recipientId(\"1\")\n                            .routingOrder(1)\n                            .hostName(user.getName()) // this should be the user name returned in AuthenticationListener.onSuccess\n                            .hostEmail(user.getEmail()) // this should be the user email returned in AuthenticationListener.onSuccess\n                            .signerName(\"John Doe\")\n                            .signerEmail(\"john.doe@abc.com\")\n                            .type(DSRecipientType.IN_PERSON_SIGNER)\n                            .tab(new DSTab.Builder()\n                                    .documentId(\"1\")\n                                    .recipientId(\"1\")\n                                    .pageNumber(1) // the page on which this tab should appear\n                                    .xPosition(123) // the x-coordinate on page 1 where you want the signer's signature\n                                    .yPosition(123) // the y-coordinate on page 1 where you want the signer's signature\n                                    .type(DSTabType.SIGNATURE)\n                                    .build())\n                            .build())\n                    .recipient(new DSEnvelopeRecipient.Builder()\n                            .recipientId(\"2\")\n                            .routingOrder(1)\n                            .hostName(user.getName()) // this should be the user name returned in AuthenticationListener.onSuccess\n                            .hostEmail(user.getEmail()) // this should be the user email returned in AuthenticationListener.onSuccess\n                            .signerName(\"Jane Doe\")\n                            .signerEmail(\"jane.doe@abc.com\")\n                            .type(DSRecipientType.IN_PERSON_SIGNER)\n                            .tab(new DSTab.Builder()\n                                    .documentId(\"1\")\n                                    .recipientId(\"2\")\n                                    .pageNumber(1) // the page on which this tab should appear\n                                    .xPosition(456) // the x-coordinate on page 1 where you want the signer's signature\n                                    .yPosition(456) // the y-coordinate on page 1 where you want the signer's signature\n                                    .type(DSTabType.SIGNATURE)\n                                    .build())\n                            .build())\n                    .recipient(new DSEnvelopeRecipient.Builder() // this recipient receives a copy\n                            .recipientId(\"3\")\n                            .routingOrder(2)\n                            .signerName(\"Jack Doe\") // if someone needs a signed copy, their name here\n                            .signerEmail(\"jack.doe@abc.com\") // if someone needs a signed copy, their valid email here\n                            .type(DSRecipientType.CARBON_COPY)\n                            .build())\n                    .textCustomField(\n                            new DSTextCustomField.Builder() // this is for free-form metadata\n                                    .fieldId(123)\n                                    .name(\"metadata1\")\n                                    .value(\"some value\")\n                                    .build()\n                    )\n                    .build();\n        } catch (DSEnvelopeException | DSAuthenticationException exception) {\n            // TODO: handle errors with envelope creation. exception.getMessage() will indicate what went wrong\n        }\n}\n```\n\n## Sending/Storing an Envelope\nThe following example assumes the envelope object from the above Envelope Creation section.\n```java\ntry {\n    DSEnvelopeDelegate docusignEnvelopeDelegate = Docusign.getInstance().getEnvelopeDelegate();\n    docusignEnvelopeDelegate.composeAndSendEnvelope(envelope, new ComposeAndSendEnvelopeListener() {\n        @Override\n        public void onSuccess(@NonNull String envelopeId) {\n            // At this point, the Envelope will be successfully created in local db store\n            // TODO: this is where Signing will kickoff\n        }\n \n        @Override\n        public void onError(@NonNull DSEnvelopeException exception) {\n            // TODO: handle failed envelope creation. exception.getMessage() will indicate what went wrong\n        }\n    });\n} catch (DocusignNotInitializedException exception) {\n    // TODO: handle error. This means the SDK object was not properly initialized\n}\n```\n\n## Deleting an Envelope from local storage\nThe following example assumes you know the envelopeId you want to delete.\n```java\ntry {\n    DSEnvelopeDelegate docusignEnvelopeDelegate = Docusign.getInstance().getEnvelopeDelegate();\n    docusignEnvelopeDelegate.deleteCachedEnvelope(envelopeId, new DSDeleteCachedEnvelopeListener() {\n        @Override\n        public void onSuccess(@NonNull String envelopeId) {\n            // TODO: handle successful envelope deletion\n        }\n \n        @Override\n        public void onError(@NonNull DSEnvelopeException exception) {\n            // TODO: handle error with envelope deletion. exception.getMessage() will indicate what went wrong\n        }\n    });\n} catch (DocusignNotInitializedException exception) {\n    // TODO: handle error. This means the SDK object was not properly initialized\n}\n```\n\n## Signing an Envelope\n### Signing offline\nSigning an envelope offline\n\n```java\nDSSigningDelegate signingDelegate = Docusign.getInstance().getSigningDelegate();\nsigningDelegate.signOffline(\n                context,\n                envelopeId,  // envelopeId of the envelope which is created locally\n                new DSOfflineSigningListener() {\n                    @Override\n                    public void onSuccess(@NotNull String envelopeId) {\n                        // TODO: Handle when envelope is successfully signed offline\n                    }\n                     \n                    @Override\n                    public void onError(@NotNull DSSigningException exception) {\n                        // TODO: Handle when error occurred during offline signing ceremony.\n                    }\n \n                    @Override\n                    public void onCancel(@NotNull String envelopeId) {\n                        // TODO: Handle when offline signing ceremony is cancelled\n                    }\n                });\n```\n\n### Signing online\nSigning an envelope online\n\n```java\nDSSigningDelegate signingDelegate = Docusign.getInstance().getSigningDelegate();\nsigningDelegate.signOnline(\n                context,\n                serverEnvelopeId,      // Envelope Id of the envelope created in Docusign portal\n                new DSOnlineSigningListener() {\n                    @Override\n                    public void onStart(@NotNull String envelopeId) {\n                        // TODO: Handle when Online Signing started\n                    }\n \n                    @Override\n                    public void onSuccess(@NotNull String envelopeId) {\n                        // TODO: Handle when Online Signing ceremony is successful\n                    }\n                     \n                    @Override\n                    public void onError(String envelopeId, @NotNull DSSigningException exception) {\n                        // TODO: Handle when error occurred during Online Signing ceremony\n                    }\n \n                    @Override\n                    public void onCancel(@NotNull String envelopeId, @NotNull String recipientId) {\n                        // TODO: Handle when Online Signing ceremony is cancelled\n                    }\n \n                    @Override\n                    public void onRecipientSigningError(@NotNull String envelopeId, @NotNull String recipientId, @NotNull DSSigningException exception) {\n                        // TODO: Handle when error occurred during Online Signing ceremony for a signer\n                    }\n \n                    @Override\n                    public void onRecipientSigningSuccess(@NotNull String envelopeId, @NotNull String recipientId) {\n                        // TODO: Handle when Online Signing is successful for a signer\n                    }\n                });\n```\n\n\n\n## Syncing an envelope\nThe following example assumes you know the envelopeId you want to sync.\n```java\ntry {\n    DSEnvelopeDelegate envelopeDelegate = Docusign.getInstance().getEnvelopeDelegate();\n    envelopeDelegate.syncEnvelope(envelopeId, new DSSyncEnvelopeListener() {\n        @Override\n        public void onSuccess(@NonNull String localEnvelopeId, String serverEnvelopeId) {\n            // At this point, envelope with localEnvelopeId is synced successfully and a new envelope Id is returned from\n            // server which can be accessed using serverEnvelopeId\n            // TODO: handle successful envelope syncing\n        }\n \n        @Override\n        public void onError(@NonNull DSSyncException exception, @NonNull String localEnvelopeId, Integer syncRetryCount) {\n            // At this point, envelope with localEnvelopeId failed to sync. DSSyncException errorCode and errorMsg gives\n            // the reason for sync failure. syncRetryCount tells the number of times envelope sync failed\n            // TODO: handle error with envelope syncing. exception.getMessage() will indicate what went wrong\n        }\n    }, true); // passing true, deletes the envelope in Database after syncing it to the cloud.\n              // Setting it to false, will retain the envelope in db with all the necessary information. An explicit clean up is required on your end to keep the db clean.\n} catch (DocusignNotInitializedException exception) {\n    // TODO: handle error. This means the SDK object was not properly initialized\n}\n```\n\n## Syncing all envelopes\nThe following example will sync all Sync Pending envelopes.\n```java\ntry {\n    DSEnvelopeDelegate envelopeDelegate = Docusign.getInstance().getEnvelopeDelegate();\n    envelopeDelegate.syncAllEnvelopes(new DSSyncAllEnvelopesListener() {\n        @Override\n        public void onStart() {\n            // TODO: handle on start of syncing of all envelopes\n        }\n        @Override\n        public void onEnvelopeSyncSuccess(@NonNull String localEnvelopeId, String serverEnvelopeId) {\n            // At this point, envelope with localEnvelopeId is synced successfully and\n            // server returned the synced envelope Id: serverEnvelopeId\n            // TODO: handle successful envelope sync of envelope with Id localenvelopeId\n        }\n \n        @Override\n        public void onEnvelopeSyncError(@NonNull DSSyncException exception, @NonNull String localEnvelopeId, Integer syncRetryCount) {\n            // At this point, envelope with localEnvelopeId failed to sync. DSSyncException errorCode and errorMsg gives\n            // the reason for sync failure. syncRetryCount tells the number of times envelope sync failed\n            // TODO: handle error with envelope syncing of envelope with Id localenvelopeId\n        }\n        @Override\n        public void onComplete(@Nullable List\u003cString\u003e failedEnvelopeIdList) {\n            // failedEnvelopeIdList will have the list of all sync failed envelope Ids. It will be null\n            // if all envelopes are synced successfully\n            // TODO: handle successful sync of the envelopes\n        }\n \n        @Override\n        public void onError(DSException exception) {\n                // TODO: handle error with envelopes syncing\n        }\n    }, true); // passing true, deletes the envelopes in Database after synching it to the cloud.\n             // Setting it to false, will retain the envelopes in db with all the necessary information. An explicit clean up is required on your end to keep the db clean.\n} catch (DocusignNotInitializedException exception) {\n    // TODO: handle error. This means the SDK object was not properly initialized\n}\n```\n\n## Transition from demo environment to production environment\nIf you’re using the demo environment, check that you set the environment after creating the Docusign instance as follows:\n```java\n    Docusign.getInstance().setEnvironment(DSEnvironment.DEMO_ENVIRONMENT);\n```\n\nIf you’re using the production environment, check that you set the environment after creating the Docusign instance as follows:\n```java\n    Docusign.getInstance().setEnvironment(DSEnvironment.PRODUCTION_ENVIRONMENT);\n```\n\n## ESign REST API invocation from SDK\nThe following example shows how to retrieve user signature using eSign REST API from Docusign Android SDK:\n### Java\n```java\nprivate void getUserSignatureInfo() {\n            DSESignApiDelegate eSignApiDelegate = Docusign.getInstance().getESignApiDelegate();\n            final UsersApi usersApi = eSignApiDelegate.createApiService(UsersApi.class);\n            if (usersApi != null) {\n                DSAuthenticationDelegate authDelegate = Docusign.getInstance().getAuthenticationDelegate();\n                final DSUser user = authDelegate.getLoggedInUser(getApplicationContext());\n\n                eSignApiDelegate.invoke(new DSESignApiListener() {\n\n                    @Override\n                    public \u003cT\u003e void onSuccess(T response) {\n                        if (response instanceof UserSignaturesInformation) {\n                            UserSignature userSignature = ((UserSignaturesInformation) response).getUserSignatures().get(0);\n                            Log.d(TAG, \"Signature Id: \" + userSignature.getSignatureId());\n                        }\n                    }\n\n                    @Override\n                    public void onError(@NotNull DSRestException exception) {\n                        // TODO: Handle error\n                    }\n                }, new Function0\u003cCall\u003cUserSignaturesInformation\u003e\u003e(){\n\n                    @Override\n                    public Call\u003cUserSignaturesInformation\u003e invoke() {\n                        return usersApi.userSignaturesGetUserSignatures(user.getAccountId(), user.getUserId(), \"signature\");\n                    }\n                });\n            }\n}\n```\n\n### Kotlin\n``` kotlin\nprivate fun getUserSignatureInfo() {\n  val eSignApiDelegate = Docusign.getInstance().getESignApiDelegate()\n  val usersApi = eSignApiDelegate.createApiService(UsersApi::class.java)\n\n  val authDelegate = Docusign.getInstance().getAuthenticationDelegate()\n  val user = authDelegate.getLoggedInUser(context)\n  eSignApiDelegate.invoke(object : DSESignApiListener {\n\n                            override fun \u003cT\u003e onSuccess(response: T?) {\n                                if (response is UserSignaturesInformation) {\n                                    val userSignature = (response as UserSignaturesInformation).getUserSignatures().get(0)\n                                    Log.d(TAG, \"Signature Id: \" + userSignature.getSignatureId());\n                                }\n                            }\n\n                            override fun onError(exception: DSRestException) {\n                                // TODO: Handle error\n                            }\n                            }) {\n                                usersApi.userSignaturesGetUserSignatures(user.getAccountId(), user.getUserId(), \"signature\")\n                            }\n}\n```\n\n## Captive Signing\nTo perform captive signing using signing URL, you can invoke the following API:\n```java\n    DSSigningDelegate signingDelegate = Docusign.getInstance().getSigningDelegate();\n        signingDelegate.launchCaptiveSigning(context,\n                signingURL,\n                envelopeId,\n                recipientId,\n                new DSCaptiveSigningListener() {\n\n                    @Override\n                    public void onSuccess(@NonNull String envelopeId) {\n                        // TODO: Handle when captive signing ceremony is succefully completed.\n                    }\n\n                    @Override\n                    public void onStart(@NonNull String envelopeId) {\n                        // TODO: Handle when captive signing ceremony is about to start\n                    }\n\n                    @Override\n                    public void onRecipientSigningSuccess(@NonNull String envelopeId, @NonNull String recipientId) {\n                        // TODO: Handle when recipient finished signing\n                    }\n\n                    @Override\n                    public void onRecipientSigningError(@NonNull String envelopeId, @NonNull String recipientId, @NonNull DSSigningException exception) {\n                        // TODO: Handle when error occured during recipient signing\n                    }\n\n                    @Override\n                    public void onError(String envelopeId, DSSigningException exception) {\n                        // TODO: Handle when error occured during captive signing ceremony\n                    }\n\n                    @Override\n                    public void onCancel(@NonNull String envelopeId, @NonNull String recipientId) {\n                        // TODO: Handle when captive signing ceremony is cancelld.\n                    }\n                });\n```\n\n## Auto place tags\nYou can create local envelope using Auto place tags based on the anchor string instead of x, y positions using the following API:\n\n```java\n    try {\n            DSUser user = Docusign.getInstance().getAuthenticationDelegate().getLoggedInUser(context);\n            DSEnvelope  envelope = new DSEnvelope.Builder()\n                    .envelopeName(\"[ENVELOPE NAME HERE]\")\n                    .document(new DSDocument.Builder()\n                            .documentId(\"1\")\n                            .uri(\"file://path_to_your_pdf_file_here\")\n                            .name(\"[DOCUMENT NAME HERE]\")\n                            .build())\n                    .recipient(new DSEnvelopeRecipient.Builder()\n                            .recipientId(\"1\")\n                            .routingOrder(1)\n                            .hostName(user.getName()) // this should be the user name returned in AuthenticationListener.onSuccess\n                            .hostEmail(user.getEmail()) // this should be the user email returned in AuthenticationListener.onSuccess\n                            .signerName(\"John Doe\")\n                            .signerEmail(\"john.doe@abc.com\")\n                            .type(DSRecipientType.IN_PERSON_SIGNER)\n                            .tab(new DSTab.Builder()\n                                    .documentId(\"1\")\n                                    .recipientId(\"1\")\n                                    .pageNumber(1) // the page on which this tab should appear\n                                    .anchorString(\"Signature\") // Auto places signature tags in the document based on the specified anchor string.\n                                    .type(DSTabType.SIGNATURE)\n                                    .build())\n                            .build())\n                    .recipient(new DSEnvelopeRecipient.Builder()\n                            .recipientId(\"2\")\n                            .routingOrder(1)\n                            .hostName(user.getName()) // this should be the user name returned in AuthenticationListener.onSuccess\n                            .hostEmail(user.getEmail()) // this should be the user email returned in AuthenticationListener.onSuccess\n                            .signerName(\"John Doe\")\n                            .signerEmail(\"john.doe@abc.com\")\n                            .type(DSRecipientType.IN_PERSON_SIGNER)\n                            .tab(new DSTab.Builder()\n                                    .documentId(\"1\")\n                                    .recipientId(\"2\")\n                                    .pageNumber(1) // the page on which this tab should appear\n                                    .anchorString(\"Signature\") // Auto places signature tags in the document based on the specified anchor string.\n                                    .type(DSTabType.SIGNATURE)\n                                    .build())\n                            .build())\n                    .recipient(new DSEnvelopeRecipient.Builder() // this recipient receives a copy\n                            .recipientId(\"3\")\n                            .routingOrder(2)\n                            .signerName(\"Jack Doe\") // if someone needs a signed copy, their name here\n                            .signerEmail(\"jack.doe@abc.com\") // if someone needs a signed copy, their valid email here\n                            .type(DSRecipientType.CARBON_COPY)\n                            .build())\n                    .textCustomField(\n                            new DSTextCustomField.Builder() // this is for free-form metadata\n                                    .fieldId(123)\n                                    .name(\"metadata1\")\n                                    .value(\"some value\")\n                                    .build()\n                    )\n                    .build();\n        } catch (DSEnvelopeException | DSAuthenticationException exception) {\n            // TODO: handle errors with envelope creation. exception.getMessage() will indicate what went wrong\n        }\n```\n\n## SDK Documentation\n* [SDK API Docs](./docs)\n* [SDK eSign API Docs](./docs)\n\nSupport\n===========\n* [FAQ for Docusign Android SDK](https://www.docusign.com/blog/developers/docusign-android-sdk-faq) \n* Reach out via developer community on Stack Overflow, search the [DocusignAPI](https://stackoverflow.com/questions/tagged/docusignapi) tag.\n* Open an [issue](https://github.com/docusign/mobile-android-sdk/issues).\n\nLicense\n=======\n\nThe Docusign Mobile Android SDK is licensed under the following [License](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocusign%2Fmobile-android-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdocusign%2Fmobile-android-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocusign%2Fmobile-android-sdk/lists"}