Camera scanning with SocketCam

Support

The Flutter CaptureSDK now has support for SocketCam C820 and C860.

Requirements

In order to use SocketCam in your Flutter app, you will need to install or upgrade the Flutter CaptureSDK version 2.0.

iOS Requirements

You will need to update pods with pod install --repo-update.

In your Info.plist, you need to add the key to allow access to the camera. Add the below code to the bottom of your dict tag.

<key>NSCameraUsageDescription</key>
        <string>Need to enable camera access for SocketCam products</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<key>UISupportedExternalAccessoryProtocols</key>
<array>
<string>com.socketmobile.chs</string>
</array>
<key>NSCameraUsageDescription</key>
<string>Need to enable camera access for SocketCam products</string>
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>sktcompanion</string>
</array>

Android Requirements

In AndroidManifest.xml you will need to add the below code.

<meta-data android:name="com.socketmobile.capture.APP_KEY" android:value="{YOUR_APP_KEY}"/>
<meta-data android:name="com.socketmobile.capture.DEVELOPER_ID" android:value="{YOUR_DEVELOPER_ID}"/>

You might also have to add the file network_security_config.xml file to android/app/src/main/res/xml in order to avoid a clearText permissions error. See the code below for the file.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="false" />
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="false">localhost</domain>
        <domain includeSubdomains="false">127.0.0.1</domain>
    </domain-config>
</network-security-config>

Then, in your AndroidManifest.xml, in your first application tag, add this property:

android:networkSecurityConfig="@xml/network_security_config"

For more information, check out the Android docs.

Using SocketCam

Once you have all of the changes above, you can start using SocketCam in your Flutter App. In order to do this, in your app you will need to first enable SocketCam, using a setProperty to set the socketCamStatus property. Once it is enabled, to open the view finder and start scanning you can set the trigger by setting the trigger property.

Below is an example of enabling SocketCam.

Future<void> _setSocketCamStatus(int? arg) async {
    CaptureProperty property = CaptureProperty(
        id: CapturePropertyIds.socketCamStatus,
        type: CapturePropertyTypes.byte,
        value: arg,
    );

    try {
        await widget.socketCamCapture?.setProperty(property);
        setStatus('successfully changed socket cam status');
    } on CaptureException catch (exception) {
        setStatus('failed to set socket cam status: ${exception.code} : ${exception.message}');
    }
}

Triggering SocketCam

SocketCam can be displayed in two modes: full-screen and custom view. The availability of each mode depends on the platform.

Full-screen mode

Full-screen mode uses the SDK’s native camera UI. This is the simplest integration and works on both platforms.

On iOS, call setTrigger(Trigger.start) then present the native view controller:

await device.setTrigger(Trigger.start);
await SocketCamView.presentFullScreen(); // iOS only

On Android, calling setTrigger(Trigger.start) is sufficient — the SDK opens its own full-screen camera Activity automatically:

await device.setTrigger(Trigger.start);
// The SDK opens a full-screen camera Activity on Android

Custom view mode (iOS)

On iOS, you can embed the camera preview inside your own layout by mounting a SocketCamView widget. Call setTrigger(Trigger.start) first, then mount the widget:

await device.setTrigger(Trigger.start);
// In your widget tree:
SocketCamView(device: device)

Custom view mode (Android)

On Android, custom view mode requires changes to the native CaptureModule.java file. The CaptureExtension must be built with a CustomViewListener to receive the view handle needed by SocketCamFragment.

Important

CaptureExtension is a singleton — the first build() call locks in the configuration for the entire process lifetime. You cannot switch between full-screen and custom view modes at runtime on Android. Choose one mode at build time.

To enable custom view on Android:

  1. In CaptureModule.java, uncomment the CustomViewListener code in buildAndStartExtension() and the related fields/methods (see the inline comments).

  2. Mount a SocketCamView widget in your Flutter layout (minimum 400×400 pixels).

  3. Call setTrigger(Trigger.start) on the device.

See the commented code in CaptureModule.java for the full implementation.

Differentiating SocketCam from other devices

It is recommended in the UI to save the capture instance that is tied to SocketCam separately from other device capture instances as to avoid get/set property and usage conflicts. You can differentiate a SocketCam device from another device, such as a D740, by checking the device type in the device arrival event.

With CaptureHelper, you can use the SocketCamTypes set to check device types:

if (SocketCamTypes.contains(device.type)) {
    // This is a SocketCam device
}

Or retrieve the SocketCam device directly:

CaptureHelperDevice? socketCamDevice = captureHelper.getSocketCamDevice();

Checking SocketCam status

In order to check if you already have SocketCam enabled, you can use a getProperty request:

Future<void> getSocketCamStatus() async {
    CaptureProperty property = const CaptureProperty(
        id: CapturePropertyIds.socketCamStatus,
        type: CapturePropertyTypes.none,
        value: {},
    );

    try {
        var data = await capture.getProperty(property);
        // data.value contains the status byte
    } on CaptureException catch (exception) {
        // Handle error
    }
}

By checking if SocketCam is enabled you won’t need to go through the trouble of re-enabling it.