Getting Started with Flutter CaptureSDK¶
Requirements¶
The Socket Mobile CaptureSDK supports all Socket Mobile data collection devices, including camera based scanning.
Even though the Flutter CaptureSDK allows to develop an app to run on iOS and Android the underlying Capture architecture on these 2 platforms is different.
On Android there is a service is required to connect the Socket Mobile device to the Android host. This service is installed through the Socket Mobile Companion app which can be installed through the Play store.
The Companion app is not required for iOS devices, but strongly recommended, as it can be used to setup the scanner as well as get support.
There is no Windows support for the Flutter CaptureSDK at this time.
Requirements for iOS platform
For applications that need to work with barcode scanners, make sure the following requirements are met:
Your iOS application needs to be registered in our Apple MFI Approved Application list before submitting your application to the Apple Store. It will not pass the Apple Store review if this is not done.
Your application must have the string
com.socketmobile.chs
in the Supported External Protocol setting.
Your application must add some security descriptions for the Bluetooth permissions as shown here.
Requirements for both iOS and Android platforms
Your application will need a SocketMobile AppKey. Follow the link to create an AppKey. AppKeys can be generated online and at no additional cost beyond the nominal one time registration fee. The AppKey is validated by the SDK library on the device, no internet connection is required. Note: You don’t need to create your own AppKey to compile and run the sample apps.
The scanner needs to be paired with your devices in Application Mode. This can be done using Socket Mobile Companion app which can be downloaded from the App Store .
Try our Flutter sample app: Flutter Capture SDK.
SDK Installation¶
The latest SDK version is only available through a private Git repository. Please log on to your Socket Mobile’s developer account to find the detailed instructions for how to access the SDK.
Adding to pubspec.yaml
dependencies:
flutter:
sdk: flutter
capturesdk_flutter:
git:
url: https://oauth2:YOUR_PRIVATE_TOKEN@sdk.socketmobile.com/capture/flutter-capturesdk.git
version: ^1.5.11
Then run flutter pub get
.
Using Capture SDK¶
First, once the NPM package has been installed CaptureSDK can be imported as shown below:
import 'package:capturesdk/capturesdk.dart';
Here are the usual steps to follow:
Open Capture with the App credentials and provide event handler function
Handle device arrival and open the device in the event handler function
Handle device removal and close the device in the event handler function
Handle decoded data in the event handler function
Opening Capture with App credentials
The Flutter SDK is an extension of the Capture SDK
Capture capture = Capture(logger);
setState(() {
_capture = capture;
});
final AppInfo appInfo = AppInfo(
'android:com.example.example',
'MC4CFQDNCtjazxILEh8oyT6w/wlaVKqS1gIVAKTz2W6TB9EgmjS1buy0A+3j7nX4',
'ios:com.example.example',
'MC0CFA1nzK67TLNmSw/QKFUIiedulUUcAhUAzT6EOvRwiZT+h4qyjEZo9oc0ONM=',
'bb57d8e1-f911-47ba-b510-693be162686a');
try {
int? response = await capture.openClient(appInfo, _onCaptureEvent);
print('capture open successful.')
} on CaptureException catch (exception) {
print('capture open failed: ' exception.code.toString();)
}
Handle device arrival and open the device
When the application receives a Device Arrival notification, it can create a new Capture instance that represents the new device.
The application opens the device by passing GUID and the main Capture reference as arguments of the device open function.
Opening the device allows to receive the decoded data from this device.
Note
the device GUID changes everytime the device connects. It identifies a connection session with a device.
Note
If a Socket Mobile device is already connected to the host prior to the app opening Capture SDK, the device arrival notificaiton will still be sent to make the application aware that the device is connected.
Note
The second argument of the _onCaptureEvent, handle, is optional. It could be used to identify which Capture object is the source of the notification.
In the _onCaptureEvent callback passed when opening Capture you could have code similar to this handling the device arrival notification:
_onCaptureEvent(e, handle) {
if (e == null) {
return;
} else if (e.runtimeType == CaptureException) {
_updateVals("${e.code}", e.message, e.method, e.details);
return;
}
logger.log('onCaptureEvent from: ', '$handle');
switch (e.id) {
case CaptureEventIds.deviceArrival:
Capture deviceCapture = Capture(logger);
setState(() {
_deviceCapture = deviceCapture;
});
_openDeviceHelper(deviceCapture, e);
break;
case CaptureEventIds.deviceRemoval:
_closeDeviceHelper(e, handle);
break;
case CaptureEventIds.decodedData:
setState(() {
//storing scanned data in state for future use
_currentScan = e;
});
_updateVals('Decoded Data', "Successful scan!");
break;
}
}
Handle device removal and close the device
The device removal occurs when the Socket Mobile device is no longer connected to the host. It is recommended to close it.
In the _onCaptureEvent callback passed when opening Capture you could have code that executes a helper (seen above) to close the device:
Future<void> _closeDeviceHelper(e, handle) async {
String guid = e.value.guid;
String name = e.value.name;
logger.log('Device Removal =>', name + ' ($guid)');
try {
dynamic res = await _deviceCapture!.close();
if (res == 0) {
List<DeviceInfo> arr = _devices;
arr.removeWhere((element) => element.guid == guid);
setState(() {
_devices = arr;
_currentScan = null;
_deviceCapture = null;
});
}
_updateVals('Device Closed', 'Successfully removed "$name"');
} on CaptureException catch (exception) {
_updateVals('${exception.code}', 'Unable to remove "$name"',
exception.method, exception.details);
}
}
Handle decoded data in the event handler function
Each time a Socket Mobile device is successful at reading a barcode or an NFC tag, the decoded data notification is sent and can be handled as shown here:
Note
Capture does not interpret the decoded data, only the application knows how to interpret it. For demonstration purpose the decoded data can be displayed with the help of a function like this:
// **********************************
// Decoded Data
// receive the decoded data from
// a specific device
// e = {
// id: CaptureEventIds.DecodedData,
// type: CaptureEventTypes.DecodedData,
// value: {
// data: [55, 97, 100, 57, 53, 100, 97, 98, 48, 102, 102, 99, 52, 53, 57, 48, 97, 52, 57, 54, 49, 97, 51, 49, 57, 50, 99, 49, 102, 51, 53, 55],
// id: CaptureDataSourceID.SymbologyQRCode,
// name: "QR Code"
// }
// }
// **********************************
case CaptureEventIds.decodedData:
setState(() {
//storing scanned data in state for future use
_currentScan = e;
});
_updateVals('Decoded Data', "Successful scan!");
break;
// In the Widget build(...)
Text(_currentScan != null
? 'Scan from ${_currentScan!.value.name}: ' +
_currentScan!.value.data.toString()
: 'No Data'))