Android SDK

Installation

You can add FormX SDK in the app build.gradle:


allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.oursky:formx-sdk:0.1.16'
}

Configure SDK

First, you will need an Access Token and the Form ID of a Pre-Built Receipt Extractor from the FormX portal.

  1. Access Tokens:
    1. Open 'Access Token' tab of 'Manage Team' page on FormX Portal.
    2. Click 'Create Token' button
    3. Enter a name for the token and create it.
    4. Copy the access token and proceed with SDK configuration
  2. Form ID:
    1. Click 'Create new extractor' button of 'Extractors' page on FormX Portal.
    2. Select 'Receipts' in the list of built-in extractors.
    3. Enter a name for the extractor and create it.
    4. Open 'Extract' tab in your extractor detail page to obtain the Form ID.

You can then configure the FormX SDK using the access token:

import ai.formx.mobile.sdk.FormXAPIClient

// Obtain access token from FormX portal
val apiClient = FormXAPIClient("PUT_ACCESS_TOKEN_HERE")

Capture & Extract Documents (Offline Mode)

The FormX can show a camera view to help user captures a document using offline ML models. In offline mode, the camera view will highlight the detected document, and provide indiciator on the document image quality, such as unsteady camera and blurry image.

<ai.formx.mobile.sdk.camera.FormXCameraView android:id="@+id/cameraView"
                                            android:layout_width="match_parent"
                                            android:layout_height="match_parent"
                                            app:layout_constraintBottom_toTopOf="parent"
                                            app:layout_constraintEnd_toEndOf="parent"
                                            app:layout_constraintStart_toStartOf="parent"
                                            app:layout_constraintTop_toTopOf="parent" />
class CameraFragment: Fragment() {
  private lateinit var binding: CameraFragmentBinding

  override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
  ): View {
    binding = CameraFragmentBinding.inflate(inflater, container, false)
    return binding.root
  }

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding.cameraView.listener = object: FormXCameraViewListener {
      override fun onError(error: Throwable) {
        // Handle error.
      }

      override fun onStateChange(view: FormXCameraView) {
    		// Capture the document image automatically when document is detected.
        if (view.state == FormXCameraViewState.READY) {
          view.capture()
        }
      }

      override fun onCaptureImage(images: List<Bitmap>) {
        val image = images.firstOrNull() ?: return

        val bytes = ByteArrayOutputStream()
        if (!image.compress(Bitmap.CompressFormat.JPEG, 90, bytes)) {
      		// Handle error.
        }

        lifecycleScope.launch {
    			// Extract fields from the captured image data.
          apiClient.extract("PUT_FORM_ID_HERE", bytes.toByteArray())
            .catch {
        			// Handle error.
              println(it)
            }
            .collect { response ->
              handleExtractedDocument(response)
            }
        }
      }

      fun handleExtractedDocument(response: FormXAPIExtractResponse) {
        val lines = mutableListOf<String>()
        for (item in response.autoExtractionItems) {
          when (val field = item.value) {
            is FormXAutoExtractionIntItem ->
            lines += "${field.name} ${field.value}"
            is FormXAutoExtractionStringItem ->
            lines += "${field.name} ${field.value}"
            is FormXAutoExtractionPurchaseInfoItem -> {
              lines += "purchase items"
              for (purchase in field.value) {
                lines += "  ${purchase.name}: ${purchase.amount}"
              }
            }
          }
        }
        AlertDialog.Builder(requireContext())
          .setTitle("Document fields")
          .setMessage(lines.joinToString("\n"))
          .setPositiveButton("OK") { dialog, _ ->
            dialog.dismiss()
          }
          .show()
      }

      override fun onClose() {
        findNavController().popBackStack()
      }
    }
  }
}

To configure the camera view UI (e.g. look & feels, UI elements), you may pass a FormXCameraViewConfiguration to the camera view. For details, please refer to the SDK API reference.

Capture & Extract Documents (Online Mode)

Alternative to using offline ML model to detect documents, you may use FormX's online document detection APIs instead for better accuracy of splitting one image into multiple documents.

To enable online mode, change the mode of camera view when setting up:


override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
  super.onViewCreated(view, savedInstanceState)

  binding.cameraView.mode = FormXCameraModeOnline(apiClient)
  binding.cameraView.listener = object: FormXCameraViewListener {
    // ...
  }
}

Interpreting Extracted Fields

The extraction result is stored in FormXAPIExtractResponse . Each extracted field has a name and value. For detailed schema, please refer to the form fields selected on FormX portal.

API References

https://oursky.github.io/formx-sdk-documentation/android


What’s Next

Learn to use SDK to perform various tasks