Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ed80a83
Fetching coordinates for barcode
pushpender30111992 Aug 24, 2023
03cd5d1
Removing logs.
pushpender30111992 Aug 24, 2023
dd613fe
Update Scanner Native Module to expose barcode bounds and corners
ravindraguptacapgemini Aug 25, 2023
b26363a
Merge branch 'fetching-barcode-coordinates' of https://github.com/Int…
ravindraguptacapgemini Aug 25, 2023
1b58ffe
Minor changes
ravindraguptacapgemini Aug 25, 2023
c41e5a5
Updated code to pass format of code
ravindraguptacapgemini Aug 27, 2023
0434afa
Fixed code issues in iOS
ravindraguptacapgemini Aug 28, 2023
269bb81
Added feature for
ravindraguptacapgemini Aug 28, 2023
9dd2dcd
Implemented Pause/Resume, pause after capture for Scanner on Android
ravindraguptacapgemini Aug 29, 2023
cdbcbe4
Minor code changes
ravindraguptacapgemini Aug 29, 2023
4ae135e
Minor fixes for commands
ravindraguptacapgemini Aug 30, 2023
f9238d4
Minor fixes in typescript file
ravindraguptacapgemini Aug 30, 2023
8a1eef7
Exported component with Ref to support commands
ravindraguptacapgemini Sep 1, 2023
37a3c3a
Update camera android code
ravindraguptacapgemini Sep 2, 2023
1709c20
Update ios code for pauseAfterCapture property
ravindraguptacapgemini Sep 4, 2023
ea1a682
Minor fixes
ravindraguptacapgemini Sep 4, 2023
d673897
Fixed issues on iOS for property and commands
ravindraguptacapgemini Sep 4, 2023
cba6d0d
Improved camera handling
ravindraguptacapgemini Nov 21, 2023
1fc7da7
Added isActive property to control session state
ravindraguptacapgemini Nov 21, 2023
865b487
Minor fixes in iOS
ravindraguptacapgemini Nov 21, 2023
4791a36
Added startScanning, stopScanning commands to the scanner module
ravindraguptacapgemini Nov 22, 2023
d6ae3ed
Updated isActive handling to resume/pause preview
ravindraguptacapgemini Nov 22, 2023
accd48b
Stop scanner on unmount
ravindraguptacapgemini Nov 23, 2023
b9449d2
Fix import issue for useEffect
ravindraguptacapgemini Dec 1, 2023
9d8d190
Merge pull request #1 from IntelexTechnologies/fetching-barcode-coord…
ahmedtausif Sep 27, 2024
e0a62f1
Data Matrix Barcode support in iOS
ahmedtausif Sep 27, 2024
d80ad9c
Merge pull request #2 from IntelexTechnologies/data_matrix
ahmedtausif Sep 27, 2024
0a96692
Merge branch 'main' of https://github.com/IntelexTechnologies/react-n…
subhodip-intelex Oct 22, 2024
8283f12
feat: updated code for scanner view
ravindraguptacapgemini Oct 24, 2024
c54210c
removed startScanning and stopScanning methods
ravindraguptacapgemini Oct 24, 2024
8ef7c04
minor change
ravindraguptacapgemini Oct 24, 2024
ccffea8
Prettier changes
ravindraguptacapgemini Oct 24, 2024
fcab405
Camera is not starting in next sessions
ravindraguptacapgemini Oct 24, 2024
ea70ee0
replace event name with top prefixed
ravindraguptacapgemini Oct 25, 2024
25ab7e5
Minor event fixes
ravindraguptacapgemini Oct 28, 2024
7e147c5
removed dispatch modern
ravindraguptacapgemini Oct 28, 2024
6f23dfa
removed unnecessary code for commands
ravindraguptacapgemini Oct 28, 2024
bc586be
Merge pull request #4 from IntelexTechnologies/ILX-49850-3
ravindraguptacapgemini Oct 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ class ReactNativeScannerView(context: Context) : LinearLayout(context) {
.build()
private lateinit var cameraControl: CameraControl

private var isCameraRunning: Boolean = false
private var pauseAfterCapture: Boolean = false
private var isActive: Boolean = false

companion object {
private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS =
mutableListOf(
Manifest.permission.CAMERA
Expand Down Expand Up @@ -117,14 +120,15 @@ class ReactNativeScannerView(context: Context) : LinearLayout(context) {
// newSingleThreadExecutor() will let us perform analysis on a single worker thread
Executors.newSingleThreadExecutor()
) { imageProxy ->
processImageProxy(scanner, imageProxy)
processImageProxy(scanner, imageProxy, reactApplicationContext)
}
}

@SuppressLint("UnsafeOptInUsageError")
private fun processImageProxy(
barcodeScanner: BarcodeScanner,
imageProxy: ImageProxy
imageProxy: ImageProxy,
reactApplicationContext: ReactApplicationContext
) {
imageProxy.image?.let { image ->
val inputImage =
Expand All @@ -133,19 +137,30 @@ class ReactNativeScannerView(context: Context) : LinearLayout(context) {
imageProxy.imageInfo.rotationDegrees
)

if (!isCameraRunning) {
return;
}

barcodeScanner.process(inputImage)
.addOnSuccessListener { barcodeList ->
val barcode =
barcodeList.getOrNull(0) // `rawValue` is the decoded value of the barcode

barcode?.rawValue?.let { value ->
// mCameraProvider?.unbindAll() // this line will stop the camera from scanning after the first scan
if (barcodeList.isNotEmpty()) {
if (pauseAfterCapture) {
pausePreview()
}

val surfaceId = UIManagerHelper.getSurfaceId(reactApplicationContext)
val reactContext = context as ReactContext
val eventDispatcher: EventDispatcher? =
UIManagerHelper.getEventDispatcherForReactTag(
reactContext, id
)
eventDispatcher?.dispatchEvent(ReactNativeScannerViewEvent(id, value))
val eventDispatcher: EventDispatcher? = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)

barcodeList.forEach { barcode ->
barcode?.let { code ->
code.cornerPoints?.let { cornerPoints ->
code.boundingBox?.let { bounds ->
eventDispatcher?.dispatchEvent(ReactNativeScannerViewEvent(surfaceId, id, code.rawValue?: "", bounds, cornerPoints, code.format))
}
}
}
}
}
}
.addOnFailureListener {
Expand Down Expand Up @@ -186,18 +201,13 @@ class ReactNativeScannerView(context: Context) : LinearLayout(context) {
// Select back camera as a default
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

isCameraRunning = true

try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()

// Bind use cases to camera
cameraProvider.bindToLifecycle(
(reactApplicationContext.currentActivity as AppCompatActivity),
cameraSelector,
surfacePreview,
analysisUseCase
)

val camera = cameraProvider.bindToLifecycle(
(reactApplicationContext.currentActivity as AppCompatActivity),
cameraSelector,
Expand All @@ -207,9 +217,8 @@ class ReactNativeScannerView(context: Context) : LinearLayout(context) {
cameraControl = camera.cameraControl

} catch (exc: Exception) {

isCameraRunning = false
}

}, ContextCompat.getMainExecutor(context))
}

Expand All @@ -225,4 +234,43 @@ class ReactNativeScannerView(context: Context) : LinearLayout(context) {
cameraExecutor.shutdown()
mCameraProvider?.unbindAll()
}
}

private fun stopCamera() {

}

fun setPauseAfterCapture(value: Boolean) {
pauseAfterCapture = value
}

fun setIsActive(value: Boolean) {
isActive = value
}

fun pausePreview() {
if (isCameraRunning) {
isCameraRunning = false
mCameraProvider?.unbind(analysisUseCase)
}
}

fun resumePreview() {
if (!isCameraRunning) {
isCameraRunning = true

try {
val reactContext = context as ReactContext
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

// Bind use cases to camera
mCameraProvider?.bindToLifecycle(
(reactContext.currentActivity as AppCompatActivity),
cameraSelector,
analysisUseCase
)
} catch (exc: Exception) {
isCameraRunning = false
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,51 @@
package com.pushpendersingh.reactnativescanner

import android.graphics.Point
import android.graphics.Rect
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableMap
import com.facebook.react.uimanager.events.Event
import com.facebook.react.uimanager.events.RCTModernEventEmitter
import com.google.mlkit.vision.barcode.common.Barcode


class ReactNativeScannerViewEvent(viewId: Int, private val qrValue: String): Event<ReactNativeScannerViewEvent>(viewId) {
class ReactNativeScannerViewEvent(
surfaceId: Int,
viewId: Int,
private val qrValue: String,
private val rect: Rect,
private val origin: Array<Point>,
private val type: Int
) : Event<ReactNativeScannerViewEvent>(surfaceId, viewId) {

override fun getEventName(): String {
return "onQrScanned"
}

override fun dispatchModern(rctEventEmitter: RCTModernEventEmitter) {
super.dispatchModern(rctEventEmitter) // if we don't call this, the react native part won't receive the event but because of this line event call two times
rctEventEmitter.receiveEvent(
-1,
viewTag, eventName,
Arguments.createMap()
)
}

override fun getEventData(): WritableMap {
val event: WritableMap = Arguments.createMap()
event.putString("value", qrValue)
val bounds = Arguments.createMap()
bounds.putArray("origin", getPoints(origin))
bounds.putInt("width", rect.width())
bounds.putInt("height", rect.height())

event.putMap("bounds", bounds)
event.putString("data", qrValue)
if (type == Barcode.FORMAT_QR_CODE)
event.putString("type", "QR_CODE")
else
event.putString("type", "UNKNOWN")

return event
}

}
private fun getPoints(points: Array<Point>): WritableArray {
val origin: WritableArray = Arguments.createArray()
for (point in points) {
val pointData: WritableMap = Arguments.createMap()
pointData.putInt("x", point.x)
pointData.putInt("y", point.y)
origin.pushMap(pointData);
}
return origin
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.pushpendersingh.reactnativescanner

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.common.MapBuilder
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.viewmanagers.ReactNativeScannerViewManagerInterface
import com.facebook.react.viewmanagers.ReactNativeScannerViewManagerDelegate

Expand All @@ -27,6 +27,16 @@ class ReactNativeScannerViewManager(private val mCallerContext: ReactApplication
return NAME
}

@ReactProp(name = "pauseAfterCapture")
override fun setPauseAfterCapture(view: ReactNativeScannerView?, value: Boolean) {
view?.setPauseAfterCapture(value)
}

@ReactProp(name = "isActive")
override fun setIsActive(view: ReactNativeScannerView?, value: Boolean) {
view?.setIsActive(value)
}

override fun enableFlashlight(view: ReactNativeScannerView?) {
view?.enableFlashlight()
}
Expand All @@ -39,6 +49,14 @@ class ReactNativeScannerViewManager(private val mCallerContext: ReactApplication
view?.releaseCamera()
}

override fun pausePreview(view: ReactNativeScannerView?) {
view?.pausePreview()
}

override fun resumePreview(view: ReactNativeScannerView?) {
view?.resumePreview()
}

override fun createViewInstance(reactContext: ThemedReactContext): ReactNativeScannerView {
val reactnativeScannerView = ReactNativeScannerView(mCallerContext)
reactnativeScannerView.setUpCamera(mCallerContext)
Expand All @@ -48,11 +66,4 @@ class ReactNativeScannerViewManager(private val mCallerContext: ReactApplication
companion object {
const val NAME = "ReactNativeScannerView"
}

override fun getExportedCustomDirectEventTypeConstants(): Map<String?, Any> {
return MapBuilder.of(
"onQrScanned",
MapBuilder.of("registrationName", "onQrScanned")
)
}
}
Loading