OpenScan SDK Concepts, Usage, and Guidance

The OpenScan SDK provides an interface that supports third-party scanning devices for Agentry applications that are running on supported Android, iOS, WPF, and Windows Mobile devices.

This capability is supported through multi-channel input support, which refers to the ability of Agentry Client to receive data from external and third-party sources, such as barcode scanners, RFID readers, magnetic stripe readers, and camera-based scanners. Each of these data sources is defined as an alternate input channel.

Agentry Core receives input from alternate input channels at any time. Input from a channel can be triggered via a button within the application (called soft-triggering), or it can be triggered by an external hardware event, such as swiping a credit card, or pressing an external on-device scanning button (called hard-triggering). Regardless of the triggering method, Core receives data that is routed to a detail screen control, which then handles the data.

Core is separate from device hardware and device management, and simply supplies the data interface.

Alternate Input Data

Input data is the main touchpoint between Core and the input hardware. The hardware device packages data into a form that Core can process, and then delivers the package to Core.

The incoming data is packaged in a Core-defined AlternateInputChannelData class. The base implementation of this class provides information about the type of media scanned, and a string representation of that data.


A hard-triggered input device is an input device that can provide data to Core at any time, without requiring the Agentry application to do something to enable or activate the input device. Examples include a magnetic stripe reader that triggers when a user swipes a card, or a Bluetooth barcode scanner with an activation button.

When such a device is triggered:
  1. The platform's input channel implementation packages the input data into an AlternateInputChannelData object, then provides the input data back to Core asynchronously via a method in the UI Manager. The UI Manager takes ownership of the data (for example, is responsible for deleting it).
  2. The UI Manager then passes the data on to the currently open screen set, retaining ownership, since the screen set must be able to pass it to child screens, controls, and screen sets embedded in those controls, without needing to attend to passing ownership between parent and child screen sets.
  3. The screen set, in turn, passes the data to the currently active screen.
  4. The active screen then passes the data on to any controls that can handle alternate input data, until one of the controls successfully processes the data. The first control to gain access to the data is the one that currently has the "alternate input focus" (known as "scan focus" in the Win32 client). This is not the same as the "input focus" that controls have relative to the keyboard. If the control with the alternate input focus at control rejects the data, the next eligible control in the focus order gains access. This process repeats until a control accepts the data.

The controls handle the data via a method that is similar to the AgentryControl::processInput method (such as AgentryControl::processAlternateInput). That method vets and accepts data, converts it into a form that is appropriate for the control, sets the control's value (probably by calling processInput), and returns a value indicating whether the data was accepted, and whether the control retains scan focus. (In general, only tile controls should retain alternate input focus after handling data, if they have another embedded control that can handle alternate input data.) The processAlternateInput method is defined by an interface that is implemented by controls that can handle alternate input; this interface defines any other methods needed to get at related settings from the editor, and any other needed information.

The value returned by the control, regarding how it handles the input data, is parsed by the control's parent screen, which uses it to manage which control next receives the alternate input focus. In addition, the screen returns a similar value back to the screen set that called it, which in turn may need to return the value to an enclosing tile control, which in turn returns it to its own parent screen, and so on until it gets back to the UI Manager. The UI Manager destroys the data object once the topmost screen set returns.


A soft-triggered input device provides data to Agentry only when requested. For example, a camera-based barcode scanner is activated only when the user clicks a button on the screen.

The widgets of alternate-input-enabled controls must present the user with some sort of button to trigger the device. Such widgets must consult with platform-specific alternate input channels to determine whether a button is necessary and what it should look like.

When the button is clicked, the widget must call back to its control to inform it that alternate input has started. The control then informs its parent screen to set the alternate input focus to itself. If that parent screen is part of a tile, then the parent screen must inform its owning tile control, so that the tile control can also take scan focus for its own parent screen. This way, when the alternate input data arrives at the screen set, it is properly routed to the control that originally triggered it.

The widget then performs whatever platform-specific operation is necessary to acquire the input data. Once the data is available, it should be routed through the UI Manager in the same manner as for hard-triggering.

Once a widget has triggered an alternate input device, Core may need to cancel it, for example, for change of input focus or scan focus (perhaps resulting from another control-initiated alternate input), or activation of a different screen in the screen set, and so forth. Some clients might be able to resolve the situation themselves on the UI side, but not all can. It may be easier to put the detection at a locus point in Core rather than having every button in the UI check such things. When such an event occurs, Core calls a method on the UI Manager, which instructs the platform to shut down any active soft-triggered scans. In addition, Core triggers a call to the IControlObserver::update method of the control that has the scan focus, in case it needs to refresh its state (for example, it may have disabled its scan button while the scan was active).