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.
Restart the application and the new C860 will appear.
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.