Skip to main content

Paper Receipt Android SDK 2.5.1

2.5.1 builds on 2.5.0 and pairs with Activation SDK 1.3.1. Its headline changes:

  • Activation SDK 1.3.1. If you use Activation, your app now starts the Activation client itself with the user's privacy choices.
  • Sharper line items after a capture. Camera frames picked up after the shutter no longer garble line-item names.
  • Holding frame analysis during photo review. A new RecognizerView.holdFrameAnalysisAfterCapture(true) for screens that show the captured photo before scanning continues.
  • Capture and OCR fixes. A captured photo always reaches the recognizer, and queued camera frames are no longer overwritten.
warning

If you use the Activation SDK, this release contains a breaking change: you must call ActivationClient.initialize(privacy) in Application.onCreate(). See Breaking changes. Apps that don't use Activation need no code changes.

Installation​

Bump the BOM to 2.5.1. If you also use the Activation SDK, bump its BOM to 1.3.1 at the same time. The two are released as a pair (see the Android SDK Version Matrix).

build.gradle.kts
dependencies {
implementation(platform("com.microblink.blinkreceipt:blinkreceipt-bom:2.5.1"))
implementation("com.microblink.blinkreceipt:blinkreceipt-recognizer")
implementation("com.microblink.blinkreceipt:blinkreceipt-camera-ui")

// Only if you use Activation
implementation(platform("com.actualplatform:activation-bom:1.3.1"))
implementation("com.actualplatform:activation")
}

The build requirements are unchanged from 2.5.0: compileSdk 37 (or higher) and minSdk 24. Your app's targetSdk does not need to change. As with every release, recompile your app against the new version.

tip

The SDK ships its own consumer ProGuard/R8 rules and is safe under R8 full mode.

Breaking changes​

Activation: initialize the client with the user's privacy values​

This applies only if your app uses the Activation SDK. Activation SDK 1.3.1 no longer creates its client on first access. Call ActivationClient.initialize(Privacy(...)) in Application.onCreate(). Reading ActivationClient.instance before that call throws.

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()

ActivationClient.initialize(
Privacy(
sellOrShareStatus = ConsentState.UNKNOWN, // replace with the user's answers
personalizationStatus = ConsentState.UNKNOWN,
disclosureVersion = null,
rdpOwner = RdpOwner.ACTUAL,
)
)

BlinkReceiptSdk.initialize(this, initializeCallback)
}
}
  • Order doesn't matter. Call the two initialize methods in either order. Once both SDKs have started, the Paper Receipt SDK gives the Activation client its device and user identity, and does so again for a client created after close().
  • Nothing crashes if you skip it. Until the client is initialized, Activation stays off and the Paper Receipt SDK logs one error. Scanning keeps working without Activation.
  • Choosing the values. See the Activation 1.3.1 release notes and Android Ad Consent, including how to choose rdpOwner.

What's new​

Holding frame analysis while a captured photo is reviewed​

takePicture() now pauses the analysis frames that feed the recognizer at the shutter. By default RecognizerView resumes them as soon as the photo has been handed to OCR and to your CameraCaptureListener. That suits a screen that returns straight to live scanning, and needs no code change.

If your screen shows the captured photo for the user to review before scanning continues, turn on holdFrameAnalysisAfterCapture(true) during setup. It is off by default. Frames then stay paused after a capture until you call resumeFrameAnalysis(), either after a retake or once the user is back to live scanning. Without it, frames picked up while the camera drifts during the review can outvote the photo and garble line-item names.

recognizerView.recognizerCallback(cameraRecognizerCallback);
recognizerView.cameraCaptureListener(cameraCaptureListener);

// Only if you show the captured photo for review.
recognizerView.holdFrameAnalysisAfterCapture(true);

// Later, when the user retakes or returns to live scanning:
recognizerView.resumeFrameAnalysis();

A capture that fails resumes frames either way, and is reported through CameraRecognizerCallback.onException(). The bundled camera UI turns this on for you. See Reviewing a Captured Photo in the integration guide.

CameraView gains the matching public suspendFrameAnalysis() and resumeFrameAnalysis(), and the protected isFrameAnalysisSuspended() and onCaptureFailed().

Merchant-detection signals reach Activation​

ScanResults.merchantDetection(), added in 2.5.0, is now forwarded to the Activation SDK. This includes the Trip Resolution signals. A misidentified merchant on an Activation scan can now be traced to the detector responsible. It requires Activation SDK 1.3.0, and needs no code change.

Changed​

  • CameraView.captureImage() pauses analysis frames at the shutter. onImageCaptured() is unaffected and the camera stays bound. RecognizerView resumes frames as described in Holding frame analysis, so apps that use RecognizerView, directly or through the bundled camera UI, need no change. A capture that fails also resumes frames, and is reported through onError(), which RecognizerView forwards to CameraRecognizerCallback.onException(). Only an app that subclasses CameraView itself keeps frames paused after onImageCaptured(), and resumes them with resumeFrameAnalysis().

Fixed​

  • Line-item names could be garbled when the camera moved after a capture. Analysis frames kept flowing into OCR while the user reviewed the photo. Because line items are resolved by a vote across frames, blurry frames picked up while the phone was lowered could outvote the capture, turning "Purchase" into "Burchase". Prices were unaffected, because they are checked against the receipt totals. Frame delivery now follows the scan phase, and the camera is released once a non-Activation scan finishes. A direct RecognizerView integration with its own photo-review screen gets the same protection by turning on holdFrameAnalysisAfterCapture(true).
  • A captured photo could be discarded before reaching OCR. When a sharper preview frame was already waiting, the photo the user took could be dropped. A capture now always replaces the waiting frame, and a later preview frame never replaces a capture.
  • Camera frames could be overwritten while waiting for OCR. At some device orientations, the next frame overwrote the pixels of a frame that was still waiting to be read. At other orientations, every frame caused an extra full-size bitmap allocation. Both are fixed.
  • The inverted-text OCR retry sent a downscaled image to remote OCR. When OCR ran remotely, the retry uploaded a 600px image instead of the full-resolution frame. It now downscales only for on-device OCR. An on-device frame that can't be read at all now returns an empty result instead of null.
  • CameraView.captureImage() no longer throws when called before the camera has started. The failure is reported through onError() instead. Before, it was thrown to the caller, where it could cancel a Flow collector for the rest of the screen's life.

Known issues​

Receipt data extraction is unchanged from 2.5.0, so the 2.5.0 known issues still apply.

Upgrade checklist​

  • Bump the Paper Receipt BOM to 2.5.1. If you use Activation, bump the Activation BOM to 1.3.1 too.
  • If you use Activation, call ActivationClient.initialize(privacy) in Application.onCreate(), and follow the Activation 1.3.1 upgrade checklist.
  • If you use RecognizerView and show the captured photo for review, call holdFrameAnalysisAfterCapture(true) during setup and resumeFrameAnalysis() when the user returns to live scanning.
  • If you subclass CameraView, call resumeFrameAnalysis() once you are back to live preview after a capture.