Scan module integration - rezolved/rezolve_sdk_sampleapp_android GitHub Wiki
Prerequisites
To integrate scan module with rest of Rezolve systems, first you need to complete SspActManager integration (LINK NEEDED), including creation of RezolveConfiguration:
int desiredImageWidthInPixels = 400;
new ResolverConfiguration.Builder(rezolveSDK)
.enableBarcode1dResolver(true)
.enableCoreResolver(true)
.enableSspResolver(sspActManager, desiredImageWidthInPixels)
.build(this);
This will allow to "translate" result of a scan into a meaningful ContentResult
.
Dependencies
These dependencies are required by the Scan module. They should be added in a project build.gradle
:
dependencies {
def sdkScanVersion = "3.0.1"
implementation "com.rezolve.sdk:scan-android:$sdkScanVersion"
implementation "com.rezolve.sdk:scan-android-x86:$sdkScanVersion" // optional module, required for support of x86 devices
}
Permissions
The module uses device camera and audio. These permission are required for the Scan module usage.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
Please consult official Android docummentation for details about implementing runtime permissions.
Implementation
Sample implementation can be found here.
RezolveScanView
view component allows to show camera view:
<com.rezolve.sdk.views.RezolveScanView
android:id="@+id/rezolve_scan_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
RezolveScanView
instance can be found by using findViewById
:
RezolveScanView scanView = findViewById(R.id.rezolve_scan_view);
AudioScanManager
and VideoScanManager
instances allow to manipulate and use the functionality of the Scan module. AudioScanManagerProvider.getAudioScanManager()
returns an AudioScanManager
instance, and VideoScanManagerProvider.getVideoScanManager()
returns a VideoScanManager
instance. Those managers are needed to manage the module and handle data:
private AudioScanManager audioScanManager = AudioScanManagerProvider.getAudioScanManager();
private VideoScanManager videoScanManager = VideoScanManagerProvider.getVideoScanManager();
Scan module usage
First, create a listener for scan callbacks:
private final ResolveResultListener resolveResultListener = new ResolveResultListener() {
@Override
public void onProcessingStarted(@NonNull UUID uuid) {
Log.d(TAG, "onProcessingStarted: " + uuid);
processingStarted();
}
@Override
public void onProcessingFinished(@NonNull UUID uuid) {
Log.d(TAG, "onProcessingFinished: " + uuid);
processingFinished();
}
@Override
public void onProcessingUrlTriggerStarted(@NonNull UUID uuid, @NonNull UrlTrigger urlTrigger) {
Log.d(TAG, "onProcessingUrlTriggerStarted: " + uuid + " url: " + urlTrigger.getUrl());
}
@Override
public void onContentResult(@NonNull UUID uuid, @NonNull ContentResult result) {
Log.d(TAG, "onContentResult: " + result);
if(result instanceof ProductResult) {
ProductResult productResult = (ProductResult) result;
onProductResult(productResult.getProduct(), productResult.getCategoryId());
} else if(result instanceof CategoryResult) {
CategoryResult categoryResult = (CategoryResult) result;
onCategoryResult(categoryResult.getCategory(), categoryResult.getMerchantId());
} else if(result instanceof SspActResult) {
SspActResult act = (SspActResult) result;
if (act.sspAct.getPageBuildingBlocks() != null && !act.sspAct.getPageBuildingBlocks().isEmpty()) {
onSspActResult(act);
}
} else if(result instanceof SspProductResult) {
} else if(result instanceof SspCategoryResult) {
}
}
@Override
public void onResolverError(@NonNull UUID uuid, @NonNull ResolverError resolverError) {
if(resolverError instanceof ResolverError.Error) {
ResolverError.Error error = (ResolverError.Error) resolverError;
onScanError(error.rezolveError.getErrorType(), error.message);
}
}
};
Create image reader when your fragment or activity is created:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
videoScanManager.createImageReader();
}
It is recommended to check the state of required permissions each time before start of scanning in case user has revoked permissions.
If RECORD_AUDIO
permission was given you can initialize audio scan.
If CAMERA
permission was given you can initialize video scan.
@Override
protected void onResume() {
super.onResume();
ResolverResultListenersRegistry.getInstance().add(resolveResultListener);
String[] scannerPermissions = {Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
Permissions.check(this, scannerPermissions, null, null, new PermissionHandler() {
@Override
public void onGranted() {
audioScanManager.clearCache();
audioScanManager.startAudioScan();
videoScanManager.clearCache(); // clears cached scan results
videoScanManager.startCamera(); // starts camera preview
videoScanManager.attachReader(); // adds watermark detection
}
});
}
When your fragment or activity is paused, stop scan managers and remove the listener from registry to avoid memory leaks. When it goes into onDestroy state, destroy the image reader:
@Override
protected void onPause() {
super.onPause();
videoScanManager.detachReader();
audioScanManager.stopAudioScan();
audioScanManager.destroy();
ResolverResultListenersRegistry.getInstance().remove(resolveResultListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
videoScanManager.destroyImageReader();
}
It is also popular to implement Rezolve Scan module in "scan on demand" mode. In this case you should add/remove watermark reader on user's demand:
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// video scan started
videoScanManager.clearCache();
videoScanManager.attachReader();
return true;
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_UP:
// video scan stopped
videoScanManager.detachReader();
return true;
}
return false;
}
});
Torch
VideoScanManager
also provides some helper methods to operate torch:
videoScanManager.isTorchSupported(); // true if torch is supported on a device
videoScanManager.isTorchOn(); // true if torch is currently turned on
videoScanManager.setTorch(boolean isOn); // turns the torch on/off