SocketCam

The C# Capture SDK now has support for SocketCam C820 and C860 on both Android and iOS.

The application receives the decoded data with the same APIs that are used for physical readers and they can also be used to manage some of the SocketCam properties the same way you would for a physical reader. To unable SocketCam, extra steps are required and listed below.

Setup

Android

Add your credentials in the AndroidManifest.xml inside <application></application>:

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="...">
        <application android:label="..." android:networkSecurityConfig="@xml/network_security_config" android:theme="...">
                <meta-data android:name="com.socketmobile.capture.APP_KEY" android:value="<YourAppKey>" />
                <meta-data android:name="com.socketmobile.capture.DEVELOPER_ID" android:value="<YourDeveloperId>" />
        </application>
</manifest>

The Android application context should be set before opening the Capture Helper. It can be achieved by using an instance of CaptureHelper in the MainActivity.cs:

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    CaptureHelper capture = new CaptureHelper();
    capture.SetAndroidContex(this);

    Xamarin.Essentials.Platform.Init(this, savedInstanceState);
    global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
    LoadApplication(new App());
}

Note

This example is from XamarinApp.Android, the same code can be applied in Maui under Platforms->Android->MainActivity.cs

iOS

Under Xamarin, all the code to open the Capture Helper, register for events and manipulate properties should be under the Xamarin.iOS app.

For SocketCam C860 which is an enhanced version of SocketCam C820, you also need to add the following key to your Info.plist: LSApplicationQueriesSchemes (Queried URL Schemes) with a new item: sktcompanion (in lower case).:

<key>LSApplicationQueriesSchemes</key>
<array>
<string>sktcompanion</string>
</array>

Note

The Xamarin SampleApp uses Dependency Services to link the platform specific code.

Enabling SocketCam

In order to enable SocketCam, you should set the SocketCam status property to Enable:

CaptureHelper capture = new CaptureHelper();

capture.SetSocketCamStatusAsync(CaptureHelper.SocketCamStatus.Enable);

At this point you will receive the device arrival.

Triggering SocketCam

Since SocketCam is not an independent device, a scan trigger button should be added:

private void Button_TriggerScan(object sender, EventArgs e)
{
    selectedDevice.SetTriggerStartAsync();
}

Android

Triggering the scan will open SocketCam’s view in full screen.

iOS

Triggering the scan will return SocketCam’s UIViewController. Use it to display the view in full screen.

In this example, the UI element (UIViewController) is retrieved from the SetTriggerStartAsync() method and then displayed:

// Save ViewController for dismiss purpose
private UIViewController socketCamViewController;

public YourFunction()
{
    device?.SetTriggerStartAsync().ContinueWith(result =>
    {
        // To use SocketCam on iOS get the returned object and use it as a View Controller
        var resultDictionary = (NSDictionary)result.Result.ResultObject;
        var resultType = (NSString)resultDictionary[NSObject.FromObject("SKTObjectType")];

        if (resultType == "SKTSocketCamViewControllerType")
        {
            socketCamViewController = (UIViewController)resultDictionary[NSObject.FromObject("SKTSocketCamViewController")];

            if (resultViewController != null)
            {
                MainThread.BeginInvokeOnMainThread(() =>
                {
                    var currentViewController = Platform.GetCurrentUIViewController();
                    currentViewController.PresentViewController(socketCamViewController, true, null);
                });
            }
        }
    });
}

Continuing the example, the view can be dismissed as follow after scanning data and receiving the DecodedData event:

MainThread.BeginInvokeOnMainThread(() =>
{
    if (socketCamViewController != null)
    {
        socketCamViewController.DismissViewController(true, null);
    }
});

Upgrading to SocketCam C860 (Pro)

SocketCam C860 (Pro) is an enhanced and paid version of SocketCam C820. Users will have the option to upgrade to SocketCam Pro from the SocketCam view. There are no additional code changes required to support this.

If you choose to upgrade from SocketCam C820 to SocketCam C860, you will be redirected to the Socket Mobile Companion app to complete the upgrade process.

Android

Now, it is possible that you still see the C820. In that case there are two possibilities to see the C860.

  1. Restart the application and the new C860 will appear.

  2. To directly show the C860 after purchasing the license you will need to Close and re-Open your instance of the CaptureHelper. The solution is the same applied for the Deep Sleep/Idle/Doze Mode specific case with one difference (see Delay below).

You can use the lifecycle of the application OnResume() triggering CloseAsync() and OpenAsync() methods from a Capture Helper instance CaptureHelper capture = new CaptureHelper(). A delay should be added before closing the instance. It is necessary for the upgrade to be applied.

Here is an example with the Delay, in App.xaml.cs use OnResume():

MainPage rootPage;

public App()
{
    InitializeComponent();

    rootPage = new MainPage();
    MainPage = rootPage;
}

protected override void OnResume()
{
    AddDelay();
}

private async Task AddDelay()
{
    await Task.Delay(1000);
    rootPage.ReEnableConnection();
}

Note

A minimum Delay of 1 second is recommended. A bit less could work but it might break the update. A broken state would show the C860 but data cannot be retrieved. In the case, re-install the application. (The license will still be valid)

The example above in App.xaml.cs is valid for Xamarin but an extra has to be applied to Maui:

MainPage rootPage;

public App()
{
        InitializeComponent();

    MainPage = new AppShell();
    rootPage = new MainPage(true);
}

protected override void OnResume()
{
    rootPage.ReEnableConnection();
}

Note

In the provided Maui Sample App, MainPage(true) is empty. It is using static variables populated by the MainPage(). In this case, the credentials (appId, developperID, appKey), the instance of Capture Helper and the isFirstLaunch Boolean should be static to be re-used.

Note

OnResume() will be triggered when the application switches from being in the backgroud to being in the foreground. This action is also valid coming back from deep sleep mode.

Then add the following method:

public void ReEnableConnection()
{
    // List will be repopulated on OpenAsync()
    _deviceList.Clear();

    capture.CloseAsync().ContinueWith(result =>
    {
        if (SktErrors.SKTSUCCESS(result.Result))
        {
            isFirstLaunch = false;

            Open();
        }
    });
}

Note

_deviceList is the list of devices saved using the Device Arrival event. In the example provided, it is used to select and trigger a scan via a button. Make sure that _deviceList.Clear() is called before Open() and outside of CloseAsync().

The Open() method refers to the following:

public void Open()
{
    capture.OpenAsync(appId, developerId, appKey)
        .ContinueWith(result =>
        {
            System.Diagnostics.Debug.Print("Open Capture returns {0}", result.Result);
            if (SktErrors.SKTSUCCESS(result.Result))
            {
                if (isFirstLaunch)
                {
                    capture.DeviceArrival += Capture_DeviceArrival;
                    capture.DeviceRemoval += Capture_DeviceRemoval; ;
                    capture.DecodedData += Capture_DecodedData;

                    // (Android-iOS) Check if SocketCam is enabled to set the Switch
                    GetSocketCamStatusInit();
                }
            }
        });
}

Note

If you are re-using the instance of Capture Helper, already registered events should not be re-registered upon using ReEnableConnection(). This is prevented by using the Boolean isFirstLaunch.

Note

If you re-install your application, then the C820 will appear again. To re-enable the C860, trigger a scan, open the camera, tap on the Pro button and select Upgrade to SocketCam Pro. This time it will only check the validity of the license and the C860 will appear again.