Originally published at: Introducing: Capacitor Barcode Scanner Plugin - Ionic Blog
We are thrilled to bring our first Ionic + OutSystems shared plugin to the Capacitor ecosystem as a core supported plugin.
Very useful, thank you! Is there a way to use it in a Cordova project?
I canât compile due to âInconsistent JVM-target compatibility detected for tasks âcompileDebugJavaWithJavacâ (17) and âcompileDebugKotlinâ (21)â. Raising the minimum SDK version doesnât seem to be enough.
When npx cap run android
, I encounter the following error
- What went wrong:
Execution failed for task â:app:checkDebugAarMetadataâ.
> Could not resolve all files for configuration â:app:debugRuntimeClasspathâ.
> Could not find any matches for com.github.outsystems:osbarcode-android:[1.0.1, 2.0.0[ as no versions of com.github.outsystems:osbarcode-android are available.
Searched in the following locations:
- https://dl.google.com/dl/android/maven2/com/github/outsystems/osbarcode-android/maven-metadata.xml
- https://repo.maven.apache.org/maven2/com/github/outsystems/osbarcode-android/maven-metadata.xml
The plugin requires to add some lines to the gradle files, see Barcode Scanner Capacitor Plugin API | Capacitor Documentation
Is there a way to customize the UI? The current barcode scanner plugin we use allows us to add a custom overlay, but the docs donât detail if this is possible.
Cool! If you provide a viewport option for overlaying this on top of html, Iâm all in. This full-screen stuff doesnât work for me.
Does @capacitor/barcode-scanner work with an Ionic PWA?
I have it working as a native app on Android, but not PWA on Android or iOS. The PWA on Android and iOS just shows a white box at the top of the browser window when launching the scanner.
Note: @capacitor/barcode-scanner does work as PWA on the Chrome desktop browser using the laptop webcam.
Note, the @capacitor/camera does work as a PWA on Android.
I also have this issue. Did you find any solution?
I have the same problem.
Capacitor Barcode scanner works in my browser.
Does not work my mobile in the PWA app.
Also, under apps, I cannot see that the app has camera permission. May be the camera does not have permission to open in the PWA mode?
in your build.gradle (module) add these lines compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" } }
When I call the scanBarcode()
method the app crashes on Android 14, logcat:
java.lang.NoSuchFieldError: No field Companion of type
Landroidx/camera/lifecycle/ProcessCameraProvider$Companion;
in class Landroidx/camera/lifecycle/ProcessCameraProvider;
or its superclasses (declaration of 'androidx.camera.lifecycle.ProcessCameraProvider' appears in
/data/app/~~PYOnqGCRJridOweZEE2kyA==/uk.ac.imperial.epicollect.five-gOXYc2KEPuq5MlnrTdBG3g==/base.apk)
at com.outsystems.plugins.barcode.view.OSBARCScannerActivity.ScanScreen(OSBARCScannerActivity.kt:274)
at com.outsystems.plugins.barcode.view.OSBARCScannerActivity$onCreate$3$1.invoke(OSBARCScannerActivity.kt:204)
at com.outsystems.plugins.barcode.view.OSBARCScannerActivity$onCreate$3$1.invoke(OSBARCScannerActivity.kt:203)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.material3.TextKt.ProvideTextStyle(Text.kt:360)
at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:81)
at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:80)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.material3.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:73)
at com.outsystems.plugins.barcode.view.ui.theme.ThemeKt.BarcodeScannerTheme(Theme.kt:65)
at com.outsystems.plugins.barcode.view.OSBARCScannerActivity$onCreate$3.invoke(OSBARCScannerActivity.kt:203)
at com.outsystems.plugins.barcode.view.OSBARCScannerActivity$onCreate$3.invoke(OSBARCScannerActivity.kt:197)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:428)
at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:252)
at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:251)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:194)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:123)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:122)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:114)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:156)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:155)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:155)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:140)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:78)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3373)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3363)
at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3363)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3298)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:587)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:966)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:519)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:140)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:1099)
at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:131)
at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:181)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.kt:192)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:138)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:1174)
at android.view.View.dispatchAttachedToWindow(View.java:23227)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3698)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3705)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3705)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3705)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3705)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3901)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3288)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:11344)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1689)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1698)
at android.view.Choreographer.doCallbacks(Choreographer.java:1153)
at android.view.Choreographer.doFrame(Choreographer.java:1079)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1646)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
are there any missing instructions on the docs at Barcode Scanner Capacitor Plugin API | Capacitor Documentation ?
That throws
A problem occurred evaluating project ':app'.
> Could not find method kotlinOptions() for arguments [build_9rl64716ccw7gid8e6v4s7v01$_run_closure1$_closure7@1ac8ff5a] on extension 'android' of type com.android.build.gradle.internal.dsl.BaseAppModuleExtension.
into app level gradle add this to dependencies
implementation 'com.github.outsystems:osbarcode-android:1.1.5@aar'
implementation 'com.google.mlkit:barcode-scanning:17.3.0'
implementation "androidx.camera:camera-camera2:1.4.0"
implementation "androidx.camera:camera-lifecycle:1.4.0"
implementation "androidx.camera:camera-view:1.4.0"
capacitor scanner seems to be based on this cordova scanner and that cordova scanner had better gradle file with compatible library versions so it doesnât crash ⌠worked for me, had the same error, lemme know if it worked
@Asko-Dev, I had the same problem as @mirko77, and your solution fixed the issue.
Now I found another bug with the plugin.
On iOS, when rotating the device during barcode-scanning, the UI is not alligned, see my screenshots from iPad. I have tested on 3 different generations of iPads, all with the same outcome.
Landscape startup, rotating to Portrait.
Similar issue if you go from Portrait to Landscape.
Any quick fix for that ?
You could try to listen for the device rotating event and restart the scanner in PORTRAIT or LANDSCAPE accordingly.
Your idea, could be a quick fix.
But shouldnât it be the pluginâs job to redraw itself when the device is rotated?
I agree.
However, iPads have issues with other barcode scanner plugins as well, so it may not be straightforward to implement.
especially when it comes to ipad, I would just force one so it locks âŚ
const scannerConfig = {
scanOrientation: 'portrait' // or 'landscape', depending on your use case
};
CapacitorBarcodeScanner.startScan(scannerConfig);
this way it shouldnât rotate to landscape as u lock it on portrait, I have not tried it out but this is what I would assume happens based on the documentation
yes the plugin should handle it but if it doesnât ⌠locking it on one option is still better than wonky UI
I do not have an iPad to double-check but apparently, it is not possible to lock the orientation at run time if Requires full screen is not checked in the deployment settings.